def test_duplicate_save_dates(): with no_lingering_errors(): with test_tempdir('bup-tvfs-') as tmpdir: bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir environ['TZ'] = 'UTC' git.repodir = bup_dir data_path = tmpdir + '/src' os.mkdir(data_path) with open(data_path + '/file', 'w+') as tmpfile: tmpfile.write(b'canary\n') ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) for i in range(11): ex((bup_path, 'save', '-d', '100000', '-n', 'test', data_path)) repo = LocalRepo() res = vfs.resolve(repo, '/test') wvpasseq(2, len(res)) name, revlist = res[-1] wvpasseq('test', name) wvpasseq(('.', '1970-01-02-034640-00', '1970-01-02-034640-01', '1970-01-02-034640-02', '1970-01-02-034640-03', '1970-01-02-034640-04', '1970-01-02-034640-05', '1970-01-02-034640-06', '1970-01-02-034640-07', '1970-01-02-034640-08', '1970-01-02-034640-09', '1970-01-02-034640-10', 'latest'), tuple(sorted(x[0] for x in vfs.contents(repo, revlist))))
def test_long_index(): with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) w = git.PackWriter() obj_bin = struct.pack('!IIIII', 0x00112233, 0x44556677, 0x88990011, 0x22334455, 0x66778899) obj2_bin = struct.pack('!IIIII', 0x11223344, 0x55667788, 0x99001122, 0x33445566, 0x77889900) obj3_bin = struct.pack('!IIIII', 0x22334455, 0x66778899, 0x00112233, 0x44556677, 0x88990011) pack_bin = struct.pack('!IIIII', 0x99887766, 0x55443322, 0x11009988, 0x77665544, 0x33221100) idx = list(list() for i in xrange(256)) idx[0].append((obj_bin, 1, 0xfffffffff)) idx[0x11].append((obj2_bin, 2, 0xffffffffff)) idx[0x22].append((obj3_bin, 3, 0xff)) w.count = 3 name = tmpdir + '/tmp.idx' r = w._write_pack_idx_v2(name, idx, pack_bin) i = git.PackIdxV2(name, open(name, 'rb')) WVPASSEQ(i.find_offset(obj_bin), 0xfffffffff) WVPASSEQ(i.find_offset(obj2_bin), 0xffffffffff) WVPASSEQ(i.find_offset(obj3_bin), 0xff)
def test_check_repo_or_die(): with no_lingering_errors(): with test_tempdir(b'bup-tgit-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup' orig_cwd = os.getcwd() try: os.chdir(tmpdir) git.init_repo(bupdir) git.check_repo_or_die() # if we reach this point the call above passed WVPASS('check_repo_or_die') os.rename(bupdir + b'/objects/pack', bupdir + b'/objects/pack.tmp') open(bupdir + b'/objects/pack', 'w').close() try: git.check_repo_or_die() except SystemExit as e: WVPASSEQ(e.code, 14) else: WVFAIL() os.unlink(bupdir + b'/objects/pack') os.rename(bupdir + b'/objects/pack.tmp', bupdir + b'/objects/pack') try: git.check_repo_or_die(b'nonexistantbup.tmp') except SystemExit as e: WVPASSEQ(e.code, 15) else: WVFAIL() finally: os.chdir(orig_cwd)
def test_apply_to_path_restricted_access(): if is_superuser() or detect_fakeroot(): return if sys.platform.startswith('cygwin'): return # chmod 000 isn't effective. with no_lingering_errors(): with test_tempdir(b'bup-tmetadata-') as tmpdir: parent = tmpdir + b'/foo' path = parent + b'/bar' os.mkdir(parent) os.mkdir(path) clear_errors() if metadata.xattr: try: metadata.xattr.set(path, b'user.buptest', b'bup') except: print("failed to set test xattr") # ignore any failures here - maybe FS cannot do it pass m = metadata.from_path(path, archive_path=path, save_symlinks=True) WVPASSEQ(m.path, path) os.chmod(parent, 0o000) m.apply_to_path(path) print('saved_errors:', helpers.saved_errors, file=sys.stderr) expected_errors = ['utime: '] if m.linux_attr and _linux_attr_supported(tmpdir): expected_errors.append('Linux chattr: ') if metadata.xattr and m.linux_xattr: expected_errors.append("xattr.set ") WVPASS(len(helpers.saved_errors) == len(expected_errors)) for i in range(len(expected_errors)): WVPASS(str(helpers.saved_errors[i]).startswith(expected_errors[i])) clear_errors()
def test_check_repo_or_die(): with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" orig_cwd = os.getcwd() try: os.chdir(tmpdir) git.init_repo(bupdir) git.check_repo_or_die() WVPASS('check_repo_or_die') # if we reach this point the call above passed os.rename(bupdir + '/objects/pack', bupdir + '/objects/pack.tmp') open(bupdir + '/objects/pack', 'w').close() try: git.check_repo_or_die() except SystemExit as e: WVPASSEQ(e.code, 14) else: WVFAIL() os.unlink(bupdir + '/objects/pack') os.rename(bupdir + '/objects/pack.tmp', bupdir + '/objects/pack') try: git.check_repo_or_die('nonexistantbup.tmp') except SystemExit as e: WVPASSEQ(e.code, 15) else: WVFAIL() finally: os.chdir(orig_cwd)
def test_metadata_method(): with no_lingering_errors(), test_tempdir('bup-tmetadata-') as tmpdir: bup_dir = tmpdir + '/bup' data_path = tmpdir + '/foo' os.mkdir(data_path) ex('touch', data_path + '/file') ex('ln', '-s', 'file', data_path + '/symlink') test_time1 = 13 * 1000000000 test_time2 = 42 * 1000000000 utime(data_path + '/file', (0, test_time1)) lutime(data_path + '/symlink', (0, 0)) utime(data_path, (0, test_time2)) ex(bup_path, '-d', bup_dir, 'init') ex(bup_path, '-d', bup_dir, 'index', '-v', data_path) ex(bup_path, '-d', bup_dir, 'save', '-tvvn', 'test', data_path) git.check_repo_or_die(bup_dir) top = vfs.RefList(None) n = top.lresolve('/test/latest' + resolve_parent(data_path)) m = n.metadata() WVPASS(m.mtime == test_time2) WVPASS(len(n.subs()) == 2) WVPASS(n.name == 'foo') WVPASS(set([x.name for x in n.subs()]) == set(['file', 'symlink'])) for sub in n: if sub.name == 'file': m = sub.metadata() WVPASS(m.mtime == test_time1) elif sub.name == 'symlink': m = sub.metadata() WVPASS(m.mtime == 0)
def test_contents_with_mismatched_bupm_git_ordering(): with no_lingering_errors(): with test_tempdir('bup-tvfs-') as tmpdir: bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir git.repodir = bup_dir data_path = tmpdir + '/src' os.mkdir(data_path) os.mkdir(data_path + '/foo') with open(data_path + '/foo.', 'w+') as tmpfile: tmpfile.write(b'canary\n') ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) ex((bup_path, 'save', '-tvvn', 'test', '--strip', data_path)) repo = LocalRepo() tip_sref = exo(('git', 'show-ref', 'refs/heads/test'))[0] tip_oidx = tip_sref.strip().split()[0] tip_tree_oidx = exo( ('git', 'log', '--pretty=%T', '-n1', tip_oidx))[0].strip() tip_tree_oid = tip_tree_oidx.decode('hex') tip_tree = tree_dict(repo, tip_tree_oid) name, item = vfs.resolve(repo, '/test/latest')[2] wvpasseq('latest', name) expected = frozenset( (x.name, vfs.Item(oid=x.oid, meta=x.meta)) for x in (tip_tree[name] for name in ('.', 'foo', '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 == 'foo')) wvpass(S_ISDIR(item.meta)) name, item = next(((n, i) for n, i in contents if n == 'foo.')) wvpass(S_ISREG(item.meta.mode))
def test_new_commit(): with no_lingering_errors(): with test_tempdir(b'bup-tgit-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup' git.init_repo(bupdir) git.verbose = 1 w = git.PackWriter() tree = os.urandom(20) parent = os.urandom(20) author_name = b'Author' author_mail = b'author@somewhere' adate_sec = 1439657836 cdate_sec = adate_sec + 1 committer_name = b'Committer' committer_mail = b'committer@somewhere' adate_tz_sec = cdate_tz_sec = None commit = w.new_commit(tree, parent, b'%s <%s>' % (author_name, author_mail), adate_sec, adate_tz_sec, b'%s <%s>' % (committer_name, committer_mail), cdate_sec, cdate_tz_sec, b'There is a small mailbox here') adate_tz_sec = -60 * 60 cdate_tz_sec = 120 * 60 commit_off = w.new_commit(tree, parent, b'%s <%s>' % (author_name, author_mail), adate_sec, adate_tz_sec, b'%s <%s>' % (committer_name, committer_mail), cdate_sec, cdate_tz_sec, b'There is a small mailbox here') w.close() commit_items = git.get_commit_items(hexlify(commit), git.cp()) local_author_offset = localtime(adate_sec).tm_gmtoff local_committer_offset = localtime(cdate_sec).tm_gmtoff WVPASSEQ(tree, unhexlify(commit_items.tree)) WVPASSEQ(1, len(commit_items.parents)) WVPASSEQ(parent, unhexlify(commit_items.parents[0])) WVPASSEQ(author_name, commit_items.author_name) WVPASSEQ(author_mail, commit_items.author_mail) WVPASSEQ(adate_sec, commit_items.author_sec) WVPASSEQ(local_author_offset, commit_items.author_offset) WVPASSEQ(committer_name, commit_items.committer_name) WVPASSEQ(committer_mail, commit_items.committer_mail) WVPASSEQ(cdate_sec, commit_items.committer_sec) WVPASSEQ(local_committer_offset, commit_items.committer_offset) commit_items = git.get_commit_items(hexlify(commit_off), git.cp()) WVPASSEQ(tree, unhexlify(commit_items.tree)) WVPASSEQ(1, len(commit_items.parents)) WVPASSEQ(parent, unhexlify(commit_items.parents[0])) WVPASSEQ(author_name, commit_items.author_name) WVPASSEQ(author_mail, commit_items.author_mail) WVPASSEQ(adate_sec, commit_items.author_sec) WVPASSEQ(adate_tz_sec, commit_items.author_offset) WVPASSEQ(committer_name, commit_items.committer_name) WVPASSEQ(committer_mail, commit_items.committer_mail) WVPASSEQ(cdate_sec, commit_items.committer_sec) WVPASSEQ(cdate_tz_sec, commit_items.committer_offset)
def test_multiple_suggestions(): with no_lingering_errors(): with test_tempdir(b'bup-tclient-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) lw = git.PackWriter() lw.new_blob(s1) lw.close() lw = git.PackWriter() lw.new_blob(s2) lw.close() WVPASSEQ(len(glob.glob(git.repo(b'objects/pack' + IDX_PAT))), 2) c = client.Client(bupdir, create=True) WVPASSEQ(len(glob.glob(c.cachedir + IDX_PAT)), 0) rw = c.new_packwriter() s1sha = rw.new_blob(s1) WVPASS(rw.exists(s1sha)) s2sha = rw.new_blob(s2) # This is a little hacky, but ensures that we test the # code under test while (len(glob.glob(c.cachedir + IDX_PAT)) < 2 and not c.conn.has_input()): pass rw.new_blob(s2) WVPASS(rw.objcache.exists(s1sha)) WVPASS(rw.objcache.exists(s2sha)) rw.new_blob(s3) WVPASSEQ(len(glob.glob(c.cachedir + IDX_PAT)), 2) rw.close() WVPASSEQ(len(glob.glob(c.cachedir + IDX_PAT)), 3)
def test_restore_over_existing_target(): with no_lingering_errors(), test_tempdir('bup-tmetadata-') as tmpdir: path = tmpdir + '/foo' os.mkdir(path) dir_m = metadata.from_path(path, archive_path=path, save_symlinks=True) os.rmdir(path) open(path, 'w').close() file_m = metadata.from_path(path, archive_path=path, save_symlinks=True) # Restore dir over file. WVPASSEQ(dir_m.create_path(path, create_symlinks=True), None) WVPASS(stat.S_ISDIR(os.stat(path).st_mode)) # Restore dir over dir. WVPASSEQ(dir_m.create_path(path, create_symlinks=True), None) WVPASS(stat.S_ISDIR(os.stat(path).st_mode)) # Restore file over dir. WVPASSEQ(file_m.create_path(path, create_symlinks=True), None) WVPASS(stat.S_ISREG(os.stat(path).st_mode)) # Restore file over file. WVPASSEQ(file_m.create_path(path, create_symlinks=True), None) WVPASS(stat.S_ISREG(os.stat(path).st_mode)) # Restore file over non-empty dir. os.remove(path) os.mkdir(path) open(path + '/bar', 'w').close() WVEXCEPT(Exception, file_m.create_path, path, create_symlinks=True) # Restore dir over non-empty dir. os.remove(path + '/bar') os.mkdir(path + '/bar') WVEXCEPT(Exception, dir_m.create_path, path, create_symlinks=True)
def test_apply_to_path_restricted_access(): if is_superuser() or detect_fakeroot(): return if sys.platform.startswith('cygwin'): return # chmod 000 isn't effective. with no_lingering_errors(), test_tempdir('bup-tmetadata-') as tmpdir: parent = tmpdir + '/foo' path = parent + '/bar' os.mkdir(parent) os.mkdir(path) clear_errors() m = metadata.from_path(path, archive_path=path, save_symlinks=True) WVPASSEQ(m.path, path) os.chmod(parent, 000) m.apply_to_path(path) print >> sys.stderr, 'saved_errors:', helpers.saved_errors expected_errors = ['utime: '] if m.linux_attr and _linux_attr_supported(tmpdir): expected_errors.append('Linux chattr: ') if metadata.xattr and m.linux_xattr: expected_errors.append("xattr.set '") WVPASS(len(helpers.saved_errors) == len(expected_errors)) for i in xrange(len(expected_errors)): WVPASS(str(helpers.saved_errors[i]).startswith(expected_errors[i])) clear_errors()
def test_resolve_loop(): with no_lingering_errors(): with test_tempdir('bup-tvfs-resloop-') as tmpdir: resolve = vfs.resolve bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir git.repodir = bup_dir repo = LocalRepo() data_path = tmpdir + '/src' os.mkdir(data_path) symlink('loop', data_path + '/loop') ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) save_utc = 100000 ex((bup_path, 'save', '-d', str(save_utc), '-tvvn', 'test', '--strip', data_path)) save_name = strftime('%Y-%m-%d-%H%M%S', localtime(save_utc)) try: wvpasseq('this call should never return', resolve(repo, '/test/%s/loop' % save_name)) except vfs.IOError as res_ex: wvpasseq(ELOOP, res_ex.errno) wvpasseq(['', 'test', save_name, 'loop'], [name for name, item in res_ex.terminus])
def test_multiple_suggestions(): with no_lingering_errors(): with test_tempdir('bup-tclient-') as tmpdir: os.environ['BUP_MAIN_EXE'] = '../../../bup' os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) lw = git.PackWriter() lw.new_blob(s1) lw.close() lw = git.PackWriter() lw.new_blob(s2) lw.close() WVPASSEQ(len(glob.glob(git.repo('objects/pack'+IDX_PAT))), 2) c = client.Client(bupdir, create=True) WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 0) rw = c.new_packwriter() s1sha = rw.new_blob(s1) WVPASS(rw.exists(s1sha)) s2sha = rw.new_blob(s2) # This is a little hacky, but ensures that we test the # code under test while (len(glob.glob(c.cachedir+IDX_PAT)) < 2 and not c.conn.has_input()): pass rw.new_blob(s2) WVPASS(rw.objcache.exists(s1sha)) WVPASS(rw.objcache.exists(s2sha)) rw.new_blob(s3) WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 2) rw.close() WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 3)
def test_long_index(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) w = git.PackWriter() obj_bin = struct.pack('!IIIII', 0x00112233, 0x44556677, 0x88990011, 0x22334455, 0x66778899) obj2_bin = struct.pack('!IIIII', 0x11223344, 0x55667788, 0x99001122, 0x33445566, 0x77889900) obj3_bin = struct.pack('!IIIII', 0x22334455, 0x66778899, 0x00112233, 0x44556677, 0x88990011) pack_bin = struct.pack('!IIIII', 0x99887766, 0x55443322, 0x11009988, 0x77665544, 0x33221100) idx = list(list() for i in xrange(256)) idx[0].append((obj_bin, 1, 0xfffffffff)) idx[0x11].append((obj2_bin, 2, 0xffffffffff)) idx[0x22].append((obj3_bin, 3, 0xff)) w.count = 3 name = tmpdir + '/tmp.idx' r = w._write_pack_idx_v2(name, idx, pack_bin) i = git.PackIdxV2(name, open(name, 'rb')) WVPASSEQ(i.find_offset(obj_bin), 0xfffffffff) WVPASSEQ(i.find_offset(obj2_bin), 0xffffffffff) WVPASSEQ(i.find_offset(obj3_bin), 0xff)
def test_new_commit(): with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 w = git.PackWriter() tree = os.urandom(20) parent = os.urandom(20) author_name = 'Author' author_mail = 'author@somewhere' adate_sec = 1439657836 cdate_sec = adate_sec + 1 committer_name = 'Committer' committer_mail = 'committer@somewhere' adate_tz_sec = cdate_tz_sec = None commit = w.new_commit(tree, parent, '%s <%s>' % (author_name, author_mail), adate_sec, adate_tz_sec, '%s <%s>' % (committer_name, committer_mail), cdate_sec, cdate_tz_sec, 'There is a small mailbox here') adate_tz_sec = -60 * 60 cdate_tz_sec = 120 * 60 commit_off = w.new_commit(tree, parent, '%s <%s>' % (author_name, author_mail), adate_sec, adate_tz_sec, '%s <%s>' % (committer_name, committer_mail), cdate_sec, cdate_tz_sec, 'There is a small mailbox here') w.close() commit_items = git.get_commit_items(commit.encode('hex'), git.cp()) local_author_offset = localtime(adate_sec).tm_gmtoff local_committer_offset = localtime(cdate_sec).tm_gmtoff WVPASSEQ(tree, commit_items.tree.decode('hex')) WVPASSEQ(1, len(commit_items.parents)) WVPASSEQ(parent, commit_items.parents[0].decode('hex')) WVPASSEQ(author_name, commit_items.author_name) WVPASSEQ(author_mail, commit_items.author_mail) WVPASSEQ(adate_sec, commit_items.author_sec) WVPASSEQ(local_author_offset, commit_items.author_offset) WVPASSEQ(committer_name, commit_items.committer_name) WVPASSEQ(committer_mail, commit_items.committer_mail) WVPASSEQ(cdate_sec, commit_items.committer_sec) WVPASSEQ(local_committer_offset, commit_items.committer_offset) commit_items = git.get_commit_items(commit_off.encode('hex'), git.cp()) WVPASSEQ(tree, commit_items.tree.decode('hex')) WVPASSEQ(1, len(commit_items.parents)) WVPASSEQ(parent, commit_items.parents[0].decode('hex')) WVPASSEQ(author_name, commit_items.author_name) WVPASSEQ(author_mail, commit_items.author_mail) WVPASSEQ(adate_sec, commit_items.author_sec) WVPASSEQ(adate_tz_sec, commit_items.author_offset) WVPASSEQ(committer_name, commit_items.committer_name) WVPASSEQ(committer_mail, commit_items.committer_mail) WVPASSEQ(cdate_sec, commit_items.committer_sec) WVPASSEQ(cdate_tz_sec, commit_items.committer_offset)
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 test_bloom(): with no_lingering_errors(): with test_tempdir('bup-tbloom-') as tmpdir: hashes = [os.urandom(20) for i in range(100)] class Idx: pass ix = Idx() ix.name = 'dummy.idx' ix.shatable = ''.join(hashes) for k in (4, 5): b = bloom.create(tmpdir + '/pybuptest.bloom', expected=100, k=k) b.add_idx(ix) WVPASSLT(b.pfalse_positive(), .1) b.close() b = bloom.ShaBloom(tmpdir + '/pybuptest.bloom') all_present = True for h in hashes: all_present &= b.exists(h) WVPASS(all_present) false_positives = 0 for h in [os.urandom(20) for i in range(1000)]: if b.exists(h): false_positives += 1 WVPASSLT(false_positives, 5) os.unlink(tmpdir + '/pybuptest.bloom') tf = tempfile.TemporaryFile(dir=tmpdir) b = bloom.create('bup.bloom', f=tf, expected=100) WVPASSEQ(b.rwfile, tf) WVPASSEQ(b.k, 5) # Test large (~1GiB) filter. This may fail on s390 (31-bit # architecture), and anywhere else where the address space is # sufficiently limited. tf = tempfile.TemporaryFile(dir=tmpdir) skip_test = False try: b = bloom.create('bup.bloom', f=tf, expected=2**28, delaywrite=False) except EnvironmentError as ex: (ptr_width, linkage) = platform.architecture() if ptr_width == '32bit' and ex.errno == errno.ENOMEM: WVMSG( 'skipping large bloom filter test (mmap probably failed) ' + str(ex)) skip_test = True else: raise if not skip_test: WVPASSEQ(b.k, 4)
def test_misc(): with no_lingering_errors(): with test_tempdir('bup-tvfs-') as tmpdir: bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir git.repodir = bup_dir data_path = tmpdir + '/src' os.mkdir(data_path) with open(data_path + '/file', 'w+') as tmpfile: tmpfile.write(b'canary\n') symlink('file', data_path + '/symlink') ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) ex((bup_path, 'save', '-d', '100000', '-tvvn', 'test', '--strip', data_path)) repo = LocalRepo() wvstart('readlink') ls_tree = exo(('git', 'ls-tree', 'test', 'symlink')).out mode, typ, oidx, name = ls_tree.strip().split(None, 3) assert name == 'symlink' link_item = vfs.Item(oid=oidx.decode('hex'), meta=int(mode, 8)) wvpasseq('file', vfs.readlink(repo, link_item)) ls_tree = exo(('git', 'ls-tree', 'test', 'file')).out mode, typ, oidx, name = ls_tree.strip().split(None, 3) assert name == 'file' file_item = vfs.Item(oid=oidx.decode('hex'), 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(__file__) meta.size = 42 fake_item = file_item._replace(meta=meta) wvpasseq(42, vfs.item_size(repo, fake_item)) wvstart('augment_item_meta') run_augment_item_meta_tests(repo, '/test/latest/file', 7, '/test/latest/symlink', 'file') wvstart('copy_item') # FIXME: this caused StopIteration #_, file_item = vfs.resolve(repo, '/file')[-1] _, file_item = vfs.resolve(repo, '/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 test_midx_close(): fddir = b'/proc/self/fd' try: os.listdir(fddir) except Exception: # not supported, not Linux, I guess return def openfiles(): for fd in os.listdir(fddir): try: yield os.readlink(os.path.join(fddir, fd)) except OSError: pass def force_midx(objdir): args = [path.exe(), b'midx', b'--auto', b'--dir', objdir] check_call(args) with no_lingering_errors(), \ test_tempdir(b'bup-tgit-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup' git.init_repo(bupdir) # create a few dummy idxes for i in range(10): _create_idx(tmpdir, i) git.auto_midx(tmpdir) l = git.PackIdxList(tmpdir) # this doesn't exist (yet) WVPASSEQ(None, l.exists(struct.pack('18xBB', 10, 0))) for i in range(10, 15): _create_idx(tmpdir, i) # delete the midx ... # TODO: why do we need to? git.auto_midx() below doesn't?! for fn in os.listdir(tmpdir): if fn.endswith(b'.midx'): os.unlink(os.path.join(tmpdir, fn)) # and make a new one git.auto_midx(tmpdir) # check it still doesn't exist - we haven't refreshed WVPASSEQ(None, l.exists(struct.pack('18xBB', 10, 0))) # check that we still have the midx open, this really # just checks more for the kernel API ('deleted' string) for fn in openfiles(): if not b'midx-' in fn: continue WVPASSEQ(True, b'deleted' in fn) # refresh the PackIdxList l.refresh() # and check that an object in pack 10 exists now WVPASSEQ(True, l.exists(struct.pack('18xBB', 10, 0))) for fn in openfiles(): if not b'midx-' in fn: continue # check that we don't have it open anymore WVPASSEQ(False, b'deleted' in fn)
def prep_and_test_repo(name, create_repo, test_repo): with no_lingering_errors(): with test_tempdir(b'bup-t' + name) as tmpdir: bup_dir = tmpdir + b'/bup' environ[b'GIT_DIR'] = bup_dir environ[b'BUP_DIR'] = bup_dir ex((bup_path, b'init')) git.repodir = bup_dir with create_repo(bup_dir) as repo: test_repo(repo, tmpdir)
def prep_and_test_repo(name, create_repo, test_repo): with no_lingering_errors(): with test_tempdir('bup-t' + name) as tmpdir: bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir environ['BUP_MAIN_EXE'] = bup_path ex((bup_path, 'init')) git.repodir = bup_dir with create_repo(bup_dir) as repo: test_repo(repo, tmpdir)
def test_list_refs(): with no_lingering_errors(): with test_tempdir(b'bup-tgit-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup' src = tmpdir + b'/src' mkdirp(src) with open(src + b'/1', 'wb+') as f: f.write(b'something\n') with open(src + b'/2', 'wb+') as f: f.write(b'something else\n') git.init_repo(bupdir) emptyset = frozenset() WVPASSEQ(frozenset(git.list_refs()), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), emptyset) exc(bup_exe, b'index', src) exc(bup_exe, b'save', b'-n', b'src', b'--strip', src) src_hash = exo(b'git', b'--git-dir', bupdir, b'rev-parse', b'src').strip().split(b'\n') assert (len(src_hash) == 1) src_hash = unhexlify(src_hash[0]) tree_hash = unhexlify( exo(b'git', b'--git-dir', bupdir, b'rev-parse', b'src:').strip().split(b'\n')[0]) blob_hash = unhexlify( exo(b'git', b'--git-dir', bupdir, b'rev-parse', b'src:1').strip().split(b'\n')[0]) WVPASSEQ(frozenset(git.list_refs()), frozenset([(b'refs/heads/src', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([(b'refs/heads/src', src_hash)])) exc(b'git', b'--git-dir', bupdir, b'tag', b'commit-tag', b'src') WVPASSEQ( frozenset(git.list_refs()), frozenset([(b'refs/heads/src', src_hash), (b'refs/tags/commit-tag', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), frozenset([(b'refs/tags/commit-tag', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([(b'refs/heads/src', src_hash)])) exc(b'git', b'--git-dir', bupdir, b'tag', b'tree-tag', b'src:') exc(b'git', b'--git-dir', bupdir, b'tag', b'blob-tag', b'src:1') os.unlink(bupdir + b'/refs/heads/src') expected_tags = frozenset([(b'refs/tags/commit-tag', src_hash), (b'refs/tags/tree-tag', tree_hash), (b'refs/tags/blob-tag', blob_hash)]) WVPASSEQ(frozenset(git.list_refs()), expected_tags) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
def test_list_refs(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" src = tmpdir + '/src' mkdirp(src) with open(src + '/1', 'w+') as f: print f, 'something' with open(src + '/2', 'w+') as f: print f, 'something else' git.init_repo(bupdir) emptyset = frozenset() WVPASSEQ(frozenset(git.list_refs()), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), emptyset) exc(bup_exe, 'index', src) exc(bup_exe, 'save', '-n', 'src', '--strip', src) src_hash = exo('git', '--git-dir', bupdir, 'rev-parse', 'src').strip().split('\n') assert (len(src_hash) == 1) src_hash = src_hash[0].decode('hex') tree_hash = exo('git', '--git-dir', bupdir, 'rev-parse', 'src:').strip().split('\n')[0].decode('hex') blob_hash = exo('git', '--git-dir', bupdir, 'rev-parse', 'src:1').strip().split('\n')[0].decode('hex') WVPASSEQ(frozenset(git.list_refs()), frozenset([('refs/heads/src', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([('refs/heads/src', src_hash)])) exc('git', '--git-dir', bupdir, 'tag', 'commit-tag', 'src') WVPASSEQ( frozenset(git.list_refs()), frozenset([('refs/heads/src', src_hash), ('refs/tags/commit-tag', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), frozenset([('refs/tags/commit-tag', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([('refs/heads/src', src_hash)])) exc('git', '--git-dir', bupdir, 'tag', 'tree-tag', 'src:') exc('git', '--git-dir', bupdir, 'tag', 'blob-tag', 'src:1') os.unlink(bupdir + '/refs/heads/src') expected_tags = frozenset([('refs/tags/commit-tag', src_hash), ('refs/tags/tree-tag', tree_hash), ('refs/tags/blob-tag', blob_hash)]) WVPASSEQ(frozenset(git.list_refs()), expected_tags) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
def test_bloom(): with no_lingering_errors(): with test_tempdir('bup-tbloom-') as tmpdir: hashes = [os.urandom(20) for i in range(100)] class Idx: pass ix = Idx() ix.name='dummy.idx' ix.shatable = ''.join(hashes) for k in (4, 5): b = bloom.create(tmpdir + '/pybuptest.bloom', expected=100, k=k) b.add_idx(ix) WVPASSLT(b.pfalse_positive(), .1) b.close() b = bloom.ShaBloom(tmpdir + '/pybuptest.bloom') all_present = True for h in hashes: all_present &= b.exists(h) WVPASS(all_present) false_positives = 0 for h in [os.urandom(20) for i in range(1000)]: if b.exists(h): false_positives += 1 WVPASSLT(false_positives, 5) os.unlink(tmpdir + '/pybuptest.bloom') tf = tempfile.TemporaryFile(dir=tmpdir) b = bloom.create('bup.bloom', f=tf, expected=100) WVPASSEQ(b.rwfile, tf) WVPASSEQ(b.k, 5) # Test large (~1GiB) filter. This may fail on s390 (31-bit # architecture), and anywhere else where the address space is # sufficiently limited. tf = tempfile.TemporaryFile(dir=tmpdir) skip_test = False try: b = bloom.create('bup.bloom', f=tf, expected=2**28, delaywrite=False) except EnvironmentError as ex: (ptr_width, linkage) = platform.architecture() if ptr_width == '32bit' and ex.errno == errno.ENOMEM: WVMSG('skipping large bloom filter test (mmap probably failed) ' + str(ex)) skip_test = True else: raise if not skip_test: WVPASSEQ(b.k, 4)
def test_bup_lutimes(): if not xstat._bup_lutimes: return with no_lingering_errors(), test_tempdir('bup-txstat-') as tmpdir: path = tmpdir + '/foo' open(path, 'w').close() frac_ts = (0, 10**6 / 2) xstat._bup_lutimes(path, (frac_ts, frac_ts)) st = _helpers.stat(path) atime_ts = st[8] mtime_ts = st[9] WVPASSEQ(atime_ts[0], 0) WVPASS(atime_ts[1] == 0 or atime_ts[1] == frac_ts[1] * 1000) WVPASSEQ(mtime_ts[0], 0) WVPASS(mtime_ts[1] == 0 or mtime_ts[1] == frac_ts[1] * 1000)
def test_list_refs(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" src = tmpdir + '/src' mkdirp(src) with open(src + '/1', 'w+') as f: print f, 'something' with open(src + '/2', 'w+') as f: print f, 'something else' git.init_repo(bupdir) emptyset = frozenset() WVPASSEQ(frozenset(git.list_refs()), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), emptyset) exc(bup_exe, 'index', src) exc(bup_exe, 'save', '-n', 'src', '--strip', src) src_hash = exo('git', '--git-dir', bupdir, 'rev-parse', 'src').strip().split('\n') assert(len(src_hash) == 1) src_hash = src_hash[0].decode('hex') tree_hash = exo('git', '--git-dir', bupdir, 'rev-parse', 'src:').strip().split('\n')[0].decode('hex') blob_hash = exo('git', '--git-dir', bupdir, 'rev-parse', 'src:1').strip().split('\n')[0].decode('hex') WVPASSEQ(frozenset(git.list_refs()), frozenset([('refs/heads/src', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([('refs/heads/src', src_hash)])) exc('git', '--git-dir', bupdir, 'tag', 'commit-tag', 'src') WVPASSEQ(frozenset(git.list_refs()), frozenset([('refs/heads/src', src_hash), ('refs/tags/commit-tag', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), frozenset([('refs/tags/commit-tag', src_hash)])) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([('refs/heads/src', src_hash)])) exc('git', '--git-dir', bupdir, 'tag', 'tree-tag', 'src:') exc('git', '--git-dir', bupdir, 'tag', 'blob-tag', 'src:1') os.unlink(bupdir + '/refs/heads/src') expected_tags = frozenset([('refs/tags/commit-tag', src_hash), ('refs/tags/tree-tag', tree_hash), ('refs/tags/blob-tag', blob_hash)]) WVPASSEQ(frozenset(git.list_refs()), expected_tags) WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([])) WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
def test_bup_utimes(): if not xstat._bup_utimes: return with no_lingering_errors(): with test_tempdir('bup-txstat-') as tmpdir: path = tmpdir + '/foo' open(path, 'w').close() frac_ts = (0, 10**6 / 2) xstat._bup_utimes(path, (frac_ts, frac_ts)) st = _helpers.stat(path) atime_ts = st[8] mtime_ts = st[9] WVPASSEQ(atime_ts[0], 0) WVPASS(atime_ts[1] == 0 or atime_ts[1] == frac_ts[1] * 1000) WVPASSEQ(mtime_ts[0], 0) WVPASS(mtime_ts[1] == 0 or mtime_ts[1] == frac_ts[1] * 1000)
def test_server_split_with_indexes(): with no_lingering_errors(): with test_tempdir(b'bup-tclient-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) lw = git.PackWriter() c = client.Client(bupdir, create=True) rw = c.new_packwriter() lw.new_blob(s1) lw.close() rw.new_blob(s2) rw.breakpoint() rw.new_blob(s1) rw.close()
def create_test_config(): with test_tempdir(b'enc') as tmpdir: cfgfile = os.path.join(tmpdir, b'repo.conf') cfg = open(cfgfile, 'wb') cfg.write(b'[bup]\n') cfg.write(b' storage = File\n') cfg.write(b' path = %s\n' % os.path.join(tmpdir, b'repo')) cfg.write(b' cachedir = %s\n' % os.path.join(tmpdir, b'cache')) cfg.close() class DummyRepo(ConfigRepo): def finish_writing(self): pass yield tmpdir, storage.get_storage(DummyRepo(cfg_file=cfgfile), create=True)
def test_from_path_error(): if is_superuser() or detect_fakeroot(): return with no_lingering_errors(), test_tempdir('bup-tmetadata-') as tmpdir: path = tmpdir + '/foo' os.mkdir(path) m = metadata.from_path(path, archive_path=path, save_symlinks=True) WVPASSEQ(m.path, path) os.chmod(path, 000) metadata.from_path(path, archive_path=path, save_symlinks=True) if metadata.get_linux_file_attr: print >> sys.stderr, 'saved_errors:', helpers.saved_errors WVPASS(len(helpers.saved_errors) == 1) errmsg = _first_err() WVPASS(errmsg.startswith('read Linux attr')) clear_errors()
def test_server_split_with_indexes(): with no_lingering_errors(), test_tempdir('bup-tclient-') as tmpdir: os.environ['BUP_MAIN_EXE'] = '../../../bup' os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) lw = git.PackWriter() c = client.Client(bupdir, create=True) rw = c.new_packwriter() lw.new_blob(s1) lw.close() rw.new_blob(s2) rw.breakpoint() rw.new_blob(s1) rw.close()
def test_bup_utimensat(): if not xstat._bup_utimensat: return with no_lingering_errors(): with test_tempdir('bup-txstat-') as tmpdir: path = tmpdir + '/foo' open(path, 'w').close() frac_ts = (0, 10**9 / 2) xstat._bup_utimensat(_helpers.AT_FDCWD, path, (frac_ts, frac_ts), 0) st = _helpers.stat(path) atime_ts = st[8] mtime_ts = st[9] WVPASSEQ(atime_ts[0], 0) WVPASS(atime_ts[1] == 0 or atime_ts[1] == frac_ts[1]) WVPASSEQ(mtime_ts[0], 0) WVPASS(mtime_ts[1] == 0 or mtime_ts[1] == frac_ts[1])
def test_read_and_seek(): # Write a set of randomly sized files containing random data whose # names are their sizes, and then verify that what we get back # from the vfs when seeking and reading with various block sizes # matches the original content. with no_lingering_errors(): with test_tempdir(b'bup-tvfs-read-') as tmpdir: resolve = vfs.resolve bup_dir = tmpdir + b'/bup' 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)
def index_writer(): with no_lingering_errors(), test_tempdir('bup-tindex-') as tmpdir: orig_cwd = os.getcwd() try: os.chdir(tmpdir) ds = xstat.stat('.') fs = xstat.stat(lib_t_dir + '/tindex.py') ms = index.MetaStoreWriter('index.meta.tmp'); tmax = (time.time() - 1) * 10**9 w = index.Writer('index.tmp', ms, tmax) w.add('/var/tmp/sporky', fs, 0) w.add('/etc/passwd', fs, 0) w.add('/etc/', ds, 0) w.add('/', ds, 0) ms.close() w.close() finally: os.chdir(orig_cwd)
def index_writer(): with no_lingering_errors(), test_tempdir('bup-tindex-') as tmpdir: orig_cwd = os.getcwd() try: os.chdir(tmpdir) ds = xstat.stat('.') fs = xstat.stat(lib_t_dir + '/tindex.py') ms = index.MetaStoreWriter('index.meta.tmp') tmax = (time.time() - 1) * 10**9 w = index.Writer('index.tmp', ms, tmax) w.add('/var/tmp/sporky', fs, 0) w.add('/etc/passwd', fs, 0) w.add('/etc/', ds, 0) w.add('/', ds, 0) ms.close() w.close() finally: os.chdir(orig_cwd)
def test_resolve_loop(): with no_lingering_errors(): with test_tempdir('bup-tvfs-resloop-') as tmpdir: resolve = vfs.resolve lresolve = vfs.lresolve bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir git.repodir = bup_dir repo = LocalRepo() data_path = tmpdir + '/src' os.mkdir(data_path) symlink('loop', data_path + '/loop') ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) ex((bup_path, 'save', '-d', '100000', '-tvvn', 'test', '--strip', data_path)) wvexcept(vfs.Loop, resolve, repo, '/test/latest/loop')
def test_read_and_seek(): # Write a set of randomly sized files containing random data whose # names are their sizes, and then verify that what we get back # from the vfs when seeking and reading with various block sizes # matches the original content. with no_lingering_errors(): with test_tempdir('bup-tvfs-read-') as tmpdir: resolve = vfs.resolve bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir git.repodir = bup_dir repo = LocalRepo() data_path = tmpdir + '/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 xrange(5))) sizes.add(1) sizes.add(max_size) for size in sizes: write_sized_random_content(data_path, size, seed) ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) ex((bup_path, 'save', '-d', '100000', '-tvvn', 'test', '--strip', data_path)) read_sizes = set((rand.randint(1, max_size) for _ in xrange(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, '/test/latest/' + str(size)) _, item = res[-1] wvpasseq(size, vfs.item_size(repo, res[-1][1])) validate_vfs_streaming_read(repo, item, '%s/%d' % (data_path, size), read_sizes) validate_vfs_seeking_read(repo, item, '%s/%d' % (data_path, size), read_sizes)
def test_dumb_client_server(): with no_lingering_errors(): with test_tempdir(b'bup-tclient-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) open(git.repo(b'bup-dumb-server'), 'w').close() lw = git.PackWriter() lw.new_blob(s1) lw.close() c = client.Client(bupdir, create=True) rw = c.new_packwriter() WVPASSEQ(len(glob.glob(c.cachedir + IDX_PAT)), 1) rw.new_blob(s1) WVPASSEQ(len(glob.glob(c.cachedir + IDX_PAT)), 1) rw.new_blob(s2) rw.close() WVPASSEQ(len(glob.glob(c.cachedir + IDX_PAT)), 2)
def test_dumb_client_server(): with no_lingering_errors(), test_tempdir('bup-tclient-') as tmpdir: os.environ['BUP_MAIN_EXE'] = '../../../bup' os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) open(git.repo('bup-dumb-server'), 'w').close() lw = git.PackWriter() lw.new_blob(s1) lw.close() c = client.Client(bupdir, create=True) rw = c.new_packwriter() WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 1) rw.new_blob(s1) WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 1) rw.new_blob(s2) rw.close() WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 2)
def create_test_config(): with test_tempdir(b'enc') as tmpdir: if repo_conf is None: cfgfile = os.path.join(tmpdir, b'repo.conf') cfg = open(cfgfile, 'wb') cfg.write(b'[bup]\n') cfg.write(b' storage = File\n') cfg.write(b' path = %s\n' % os.path.join(tmpdir, b'repo')) cfg.write(b' cachedir = %s\n' % os.path.join(tmpdir, b'cache')) cfg.close() create = True else: wvstart("storage config from %s" % repo_conf) cfgfile = repo_conf create = False repo = DummyRepo(cfg_file=cfgfile) store = get_storage(repo, create=create) yield tmpdir, store del store
def testpacks(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 w = git.PackWriter() w.new_blob(os.urandom(100)) w.new_blob(os.urandom(100)) w.abort() w = git.PackWriter() hashes = [] nobj = 1000 for i in range(nobj): hashes.append(w.new_blob(str(i))) log('\n') nameprefix = w.close() print repr(nameprefix) WVPASS(os.path.exists(nameprefix + '.pack')) WVPASS(os.path.exists(nameprefix + '.idx')) r = git.open_idx(nameprefix + '.idx') print repr(r.fanout) for i in range(nobj): WVPASS(r.find_offset(hashes[i]) > 0) WVPASS(r.exists(hashes[99])) WVFAIL(r.exists('\0' * 20)) pi = iter(r) for h in sorted(hashes): WVPASSEQ(str(pi.next()).encode('hex'), h.encode('hex')) WVFAIL(r.find_offset('\0' * 20)) r = git.PackIdxList(bupdir + '/objects/pack') WVPASS(r.exists(hashes[5])) WVPASS(r.exists(hashes[6])) WVFAIL(r.exists('\0' * 20))
def testpacks(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 w = git.PackWriter() w.new_blob(os.urandom(100)) w.new_blob(os.urandom(100)) w.abort() w = git.PackWriter() hashes = [] nobj = 1000 for i in range(nobj): hashes.append(w.new_blob(str(i))) log('\n') nameprefix = w.close() print repr(nameprefix) WVPASS(os.path.exists(nameprefix + '.pack')) WVPASS(os.path.exists(nameprefix + '.idx')) r = git.open_idx(nameprefix + '.idx') print repr(r.fanout) for i in range(nobj): WVPASS(r.find_offset(hashes[i]) > 0) WVPASS(r.exists(hashes[99])) WVFAIL(r.exists('\0'*20)) pi = iter(r) for h in sorted(hashes): WVPASSEQ(str(pi.next()).encode('hex'), h.encode('hex')) WVFAIL(r.find_offset('\0'*20)) r = git.PackIdxList(bupdir + '/objects/pack') WVPASS(r.exists(hashes[5])) WVPASS(r.exists(hashes[6])) WVFAIL(r.exists('\0'*20))
def testpacks(): with no_lingering_errors(): with test_tempdir(b'bup-tgit-') as tmpdir: environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup' git.init_repo(bupdir) git.verbose = 1 w = git.PackWriter() w.new_blob(os.urandom(100)) w.new_blob(os.urandom(100)) w.abort() w = git.PackWriter() hashes = [] nobj = 1000 for i in range(nobj): hashes.append(w.new_blob(b'%d' % i)) log('\n') nameprefix = w.close() print(repr(nameprefix)) WVPASS(os.path.exists(nameprefix + b'.pack')) WVPASS(os.path.exists(nameprefix + b'.idx')) r = git.open_idx(nameprefix + b'.idx') print(repr(r.fanout)) for i in range(nobj): WVPASS(r.find_offset(hashes[i]) > 0) WVPASS(r.exists(hashes[99])) WVFAIL(r.exists(b'\0'*20)) pi = iter(r) for h in sorted(hashes): WVPASSEQ(hexlify(next(pi)), hexlify(h)) WVFAIL(r.find_offset(b'\0'*20)) r = git.PackIdxList(bupdir + b'/objects/pack') WVPASS(r.exists(hashes[5])) WVPASS(r.exists(hashes[6])) WVFAIL(r.exists(b'\0'*20))
def index_negative_timestamps(): with no_lingering_errors(): with test_tempdir('bup-tindex-') as tmpdir: # Makes 'foo' exist foopath = tmpdir + '/foo' f = file(foopath, 'wb') f.close() # Dec 31, 1969 os.utime(foopath, (-86400, -86400)) ns_per_sec = 10**9 tmax = (time.time() - 1) * ns_per_sec e = index.BlankNewEntry(foopath, 0, tmax) e.update_from_stat(xstat.stat(foopath), 0) WVPASS(e.packed()) # Jun 10, 1893 os.utime(foopath, (-0x80000000, -0x80000000)) e = index.BlankNewEntry(foopath, 0, tmax) e.update_from_stat(xstat.stat(foopath), 0) WVPASS(e.packed())
def test_atomically_replaced_file(): with no_lingering_errors(), test_tempdir('bup-thelper-') as tmpdir: target_file = os.path.join(tmpdir, 'test-atomic-write') with atomically_replaced_file(target_file, mode='w') as f: f.write('asdf') WVPASSEQ(f.mode, 'w') f = open(target_file, 'r') WVPASSEQ(f.read(), 'asdf') try: with atomically_replaced_file(target_file, mode='w') as f: f.write('wxyz') raise Exception() except: pass with open(target_file) as f: WVPASSEQ(f.read(), 'asdf') with atomically_replaced_file(target_file, mode='wb') as f: f.write(os.urandom(20)) WVPASSEQ(f.mode, 'wb')
def test_contents_with_mismatched_bupm_git_ordering(): with no_lingering_errors(): with test_tempdir('bup-tvfs-') as tmpdir: bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir git.repodir = bup_dir data_path = tmpdir + '/src' os.mkdir(data_path) os.mkdir(data_path + '/foo') with open(data_path + '/foo.', 'w+') as tmpfile: tmpfile.write(b'canary\n') ex((bup_path, 'init')) ex((bup_path, 'index', '-v', data_path)) save_utc = 100000 save_name = strftime('%Y-%m-%d-%H%M%S', localtime(save_utc)) ex((bup_path, 'save', '-tvvn', 'test', '-d', str(save_utc), '--strip', data_path)) repo = LocalRepo() tip_sref = exo(('git', 'show-ref', 'refs/heads/test')).out tip_oidx = tip_sref.strip().split()[0] tip_tree_oidx = exo(('git', 'log', '--pretty=%T', '-n1', tip_oidx)).out.strip() tip_tree_oid = tip_tree_oidx.decode('hex') tip_tree = tree_dict(repo, tip_tree_oid) name, item = vfs.resolve(repo, '/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 ('.', 'foo', '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 == 'foo')) wvpass(S_ISDIR(item.meta)) name, item = next(((n, i) for n, i in contents if n == 'foo.')) wvpass(S_ISREG(item.meta.mode))
def test_metadata_method(): with no_lingering_errors(): with test_tempdir('bup-tmetadata-') as tmpdir: bup_dir = tmpdir + '/bup' data_path = tmpdir + '/foo' os.mkdir(data_path) ex('touch', data_path + '/file') ex('ln', '-s', 'file', data_path + '/symlink') test_time1 = 13 * 1000000000 test_time2 = 42 * 1000000000 utime(data_path + '/file', (0, test_time1)) lutime(data_path + '/symlink', (0, 0)) utime(data_path, (0, test_time2)) ex(bup_path, '-d', bup_dir, 'init') ex(bup_path, '-d', bup_dir, 'index', '-v', data_path) ex(bup_path, '-d', bup_dir, 'save', '-tvvn', 'test', data_path) git.check_repo_or_die(bup_dir) repo = LocalRepo() resolved = vfs.resolve(repo, '/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 == 'foo') contents = tuple(vfs.contents(repo, leaf_item)) WVPASS(len(contents) == 3) WVPASSEQ(frozenset(name for name, item in contents), frozenset(('.', 'file', 'symlink'))) for name, item in contents: if name == 'file': m = item.meta WVPASS(m.mtime == test_time1) elif name == 'symlink': m = item.meta WVPASSEQ(m.symlink_target, 'file') WVPASSEQ(m.size, 4) WVPASSEQ(m.mtime, 0)
def test_pack_name_lookup(): with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 packdir = git.repo('objects/pack') idxnames = [] hashes = [] for start in range(0,28,2): w = git.PackWriter() for i in range(start, start+2): hashes.append(w.new_blob(str(i))) log('\n') idxnames.append(os.path.basename(w.close() + '.idx')) r = git.PackIdxList(packdir) WVPASSEQ(len(r.packs), 2) for e,idxname in enumerate(idxnames): for i in range(e*2, (e+1)*2): WVPASSEQ(r.exists(hashes[i], want_source=True), idxname)
def test_midx_refreshing(): with no_lingering_errors(): with test_tempdir('bup-tclient-') as tmpdir: os.environ['BUP_MAIN_EXE'] = bupmain = '../../../bup' os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) c = client.Client(bupdir, create=True) rw = c.new_packwriter() rw.new_blob(s1) p1base = rw.breakpoint() p1name = os.path.join(c.cachedir, p1base) s1sha = rw.new_blob(s1) # should not be written; it's already in p1 s2sha = rw.new_blob(s2) p2base = rw.close() p2name = os.path.join(c.cachedir, p2base) del rw pi = git.PackIdxList(bupdir + '/objects/pack') WVPASSEQ(len(pi.packs), 2) pi.refresh() WVPASSEQ(len(pi.packs), 2) WVPASSEQ(sorted([os.path.basename(i.name) for i in pi.packs]), sorted([p1base, p2base])) p1 = git.open_idx(p1name) WVPASS(p1.exists(s1sha)) p2 = git.open_idx(p2name) WVFAIL(p2.exists(s1sha)) WVPASS(p2.exists(s2sha)) subprocess.call([bupmain, 'midx', '-f']) pi.refresh() WVPASSEQ(len(pi.packs), 1) pi.refresh(skip_midx=True) WVPASSEQ(len(pi.packs), 2) pi.refresh(skip_midx=False) WVPASSEQ(len(pi.packs), 1)
def test_commit_parsing(): def restore_env_var(name, val): if val is None: del os.environ[name] else: os.environ[name] = val def showval(commit, val): return readpipe(['git', 'show', '-s', '--pretty=format:%s' % val, commit]).strip() with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir: orig_cwd = os.getcwd() workdir = tmpdir + "/work" repodir = workdir + '/.git' orig_author_name = os.environ.get('GIT_AUTHOR_NAME') orig_author_email = os.environ.get('GIT_AUTHOR_EMAIL') orig_committer_name = os.environ.get('GIT_COMMITTER_NAME') orig_committer_email = os.environ.get('GIT_COMMITTER_EMAIL') os.environ['GIT_AUTHOR_NAME'] = 'bup test' os.environ['GIT_COMMITTER_NAME'] = os.environ['GIT_AUTHOR_NAME'] os.environ['GIT_AUTHOR_EMAIL'] = 'bup@a425bc70a02811e49bdf73ee56450e6f' os.environ['GIT_COMMITTER_EMAIL'] = os.environ['GIT_AUTHOR_EMAIL'] try: readpipe(['git', 'init', workdir]) os.environ['GIT_DIR'] = os.environ['BUP_DIR'] = repodir git.check_repo_or_die(repodir) os.chdir(workdir) with open('foo', 'w') as f: print >> f, 'bar' readpipe(['git', 'add', '.']) readpipe(['git', 'commit', '-am', 'Do something', '--author', 'Someone <someone@somewhere>', '--date', 'Sat Oct 3 19:48:49 2009 -0400']) commit = readpipe(['git', 'show-ref', '-s', 'master']).strip() parents = showval(commit, '%P') tree = showval(commit, '%T') cname = showval(commit, '%cn') cmail = showval(commit, '%ce') cdate = showval(commit, '%ct') coffs = showval(commit, '%ci') coffs = coffs[-5:] coff = (int(coffs[-4:-2]) * 60 * 60) + (int(coffs[-2:]) * 60) if coffs[-5] == '-': coff = - coff commit_items = git.get_commit_items(commit, git.cp()) WVPASSEQ(commit_items.parents, []) WVPASSEQ(commit_items.tree, tree) WVPASSEQ(commit_items.author_name, 'Someone') WVPASSEQ(commit_items.author_mail, 'someone@somewhere') WVPASSEQ(commit_items.author_sec, 1254613729) WVPASSEQ(commit_items.author_offset, -(4 * 60 * 60)) WVPASSEQ(commit_items.committer_name, cname) WVPASSEQ(commit_items.committer_mail, cmail) WVPASSEQ(commit_items.committer_sec, int(cdate)) WVPASSEQ(commit_items.committer_offset, coff) WVPASSEQ(commit_items.message, 'Do something\n') with open('bar', 'w') as f: print >> f, 'baz' readpipe(['git', 'add', '.']) readpipe(['git', 'commit', '-am', 'Do something else']) child = readpipe(['git', 'show-ref', '-s', 'master']).strip() parents = showval(child, '%P') commit_items = git.get_commit_items(child, git.cp()) WVPASSEQ(commit_items.parents, [commit]) finally: os.chdir(orig_cwd) restore_env_var('GIT_AUTHOR_NAME', orig_author_name) restore_env_var('GIT_AUTHOR_EMAIL', orig_author_email) restore_env_var('GIT_COMMITTER_NAME', orig_committer_name) restore_env_var('GIT_COMMITTER_EMAIL', orig_committer_email)
def index_dirty(): with no_lingering_errors(): with test_tempdir('bup-tindex-') as tmpdir: orig_cwd = os.getcwd() try: os.chdir(tmpdir) default_meta = metadata.Metadata() ms1 = index.MetaStoreWriter('index.meta.tmp') ms2 = index.MetaStoreWriter('index2.meta.tmp') ms3 = index.MetaStoreWriter('index3.meta.tmp') meta_ofs1 = ms1.store(default_meta) meta_ofs2 = ms2.store(default_meta) meta_ofs3 = ms3.store(default_meta) ds = xstat.stat(lib_t_dir) fs = xstat.stat(lib_t_dir + '/tindex.py') tmax = (time.time() - 1) * 10**9 w1 = index.Writer('index.tmp', ms1, tmax) w1.add('/a/b/x', fs, meta_ofs1) w1.add('/a/b/c', fs, meta_ofs1) w1.add('/a/b/', ds, meta_ofs1) w1.add('/a/', ds, meta_ofs1) #w1.close() WVPASS() w2 = index.Writer('index2.tmp', ms2, tmax) w2.add('/a/b/n/2', fs, meta_ofs2) #w2.close() WVPASS() w3 = index.Writer('index3.tmp', ms3, tmax) w3.add('/a/c/n/3', fs, meta_ofs3) #w3.close() WVPASS() r1 = w1.new_reader() r2 = w2.new_reader() r3 = w3.new_reader() WVPASS() r1all = [e.name for e in r1] WVPASSEQ(r1all, ['/a/b/x', '/a/b/c', '/a/b/', '/a/', '/']) r2all = [e.name for e in r2] WVPASSEQ(r2all, ['/a/b/n/2', '/a/b/n/', '/a/b/', '/a/', '/']) r3all = [e.name for e in r3] WVPASSEQ(r3all, ['/a/c/n/3', '/a/c/n/', '/a/c/', '/a/', '/']) all = [e.name for e in index.merge(r2, r1, r3)] WVPASSEQ(all, ['/a/c/n/3', '/a/c/n/', '/a/c/', '/a/b/x', '/a/b/n/2', '/a/b/n/', '/a/b/c', '/a/b/', '/a/', '/']) fake_validate(r1) dump(r1) print [hex(e.flags) for e in r1] WVPASSEQ([e.name for e in r1 if e.is_valid()], r1all) WVPASSEQ([e.name for e in r1 if not e.is_valid()], []) WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], ['/a/c/n/3', '/a/c/n/', '/a/c/', '/a/b/n/2', '/a/b/n/', '/a/b/', '/a/', '/']) expect_invalid = ['/'] + r2all + r3all expect_real = (set(r1all) - set(r2all) - set(r3all)) \ | set(['/a/b/n/2', '/a/c/n/3']) dump(index.merge(r2, r1, r3)) for e in index.merge(r2, r1, r3): print e.name, hex(e.flags), e.ctime eiv = e.name in expect_invalid er = e.name in expect_real WVPASSEQ(eiv, not e.is_valid()) WVPASSEQ(er, e.is_real()) fake_validate(r2, r3) dump(index.merge(r2, r1, r3)) WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], []) e = eget(index.merge(r2, r1, r3), '/a/b/c') e.invalidate() e.repack() dump(index.merge(r2, r1, r3)) WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], ['/a/b/c', '/a/b/', '/a/', '/']) w1.close() w2.close() w3.close() finally: