def _test_unnamed(get_disposition, src_info): tinyfile_id = src_info['tinyfile-id'] tinyfile_path = src_info['tinyfile-path'] subtree_vfs_path = src_info['subtree-vfs-path'] wvstart(get_disposition + ' --unnamed to root fails') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path, b'.tag/subtree', b'src/latest' + subtree_vfs_path, b'.tag/commit-1', b'src/latest', b'src'): for ex_ref in (None, (item, b'.tag/obj')): exr = run_get(get_disposition, b'--unnamed', (item, b'/'), given=ex_ref) wvpassne(0, exr.rc) verify_rx(br'usage: bup get ', exr.err) wvstart(get_disposition + ' --unnamed file') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): exr = run_get(get_disposition, b'--unnamed', item) wvpasseq(0, exr.rc) validate_blob(tinyfile_id, tinyfile_id) verify_only_refs(heads=[], tags=[]) exr = run_get(get_disposition, b'--unnamed', item, given=(item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_blob(tinyfile_id, tinyfile_id) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' --unnamed tree') subtree_id = src_info['subtree-id'] for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): exr = run_get(get_disposition, b'--unnamed', item) wvpasseq(0, exr.rc) validate_tree(subtree_id, subtree_id) verify_only_refs(heads=[], tags=[]) exr = run_get(get_disposition, b'--unnamed', item, given=(item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_tree(subtree_id, subtree_id) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' --unnamed committish') save_2 = src_info['save-2'] commit_2_id = src_info['commit-2-id'] for item in (b'.tag/commit-2', b'src/' + save_2, b'src'): exr = run_get(get_disposition, b'--unnamed', item) wvpasseq(0, exr.rc) validate_commit(commit_2_id, commit_2_id) verify_only_refs(heads=[], tags=[]) exr = run_get(get_disposition, b'--unnamed', item, given=(item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_commit(commit_2_id, commit_2_id) verify_only_refs(heads=[], tags=(b'obj',))
def _test_universal(get_disposition, src_info): methods = (b'--ff', b'--append', b'--pick', b'--force-pick', b'--new-tag', b'--replace', b'--unnamed') for method in methods: mmsg = method.decode('ascii') wvstart(get_disposition + ' ' + mmsg + ', missing source, fails') exr = run_get(get_disposition, method, b'not-there') wvpassne(0, exr.rc) verify_rx(br'cannot find source', exr.err) for method in methods: mmsg = method.decode('ascii') wvstart(get_disposition + ' ' + mmsg + ' / fails') exr = run_get(get_disposition, method, b'/') wvpassne(0, exr.rc) verify_rx(b'cannot fetch entire repository', exr.err)
def create_get_src(): global bup_cmd, src_info wvstart('preparing') ex((bup_cmd, b'-d', b'get-src', b'init')) mkdir(b'src') open(b'src/unrelated', 'a').close() ex((bup_cmd, b'-d', b'get-src', b'index', b'src')) ex((bup_cmd, b'-d', b'get-src', b'save', b'-tcn', b'unrelated-branch', b'src')) ex((bup_cmd, b'-d', b'get-src', b'index', b'--clear')) rmrf(b'src') mkdir(b'src') open(b'src/zero', 'a').close() ex((bup_cmd, b'-d', b'get-src', b'index', b'src')) exr = exo((bup_cmd, b'-d', b'get-src', b'save', b'-tcn', b'src', b'src')) out = exr.out.splitlines() tree_0_id = out[0] commit_0_id = out[-1] exr = exo((bup_cmd, b'-d', b'get-src', b'ls', b'src')) save_0 = exr.out.splitlines()[0] ex((b'git', b'--git-dir', b'get-src', b'branch', b'src-0', b'src')) ex((b'cp', b'-RPp', b'src', b'src-0')) rmrf(b'src') mkdir(b'src') mkdir(b'src/x') mkdir(b'src/x/y') ex((bup_cmd + b' -d get-src random 1k > src/1'), shell=True) ex((bup_cmd + b' -d get-src random 1k > src/x/2'), shell=True) ex((bup_cmd, b'-d', b'get-src', b'index', b'src')) exr = exo((bup_cmd, b'-d', b'get-src', b'save', b'-tcn', b'src', b'src')) out = exr.out.splitlines() tree_1_id = out[0] commit_1_id = out[-1] exr = exo((bup_cmd, b'-d', b'get-src', b'ls', b'src')) save_1 = exr.out.splitlines()[1] ex((b'git', b'--git-dir', b'get-src', b'branch', b'src-1', b'src')) ex((b'cp', b'-RPp', b'src', b'src-1')) # Make a copy the current state of src so we'll have an ancestor. ex((b'cp', b'-RPp', b'get-src/refs/heads/src', b'get-src/refs/heads/src-ancestor')) with open(b'src/tiny-file', 'ab') as f: f.write(b'xyzzy') ex((bup_cmd, b'-d', b'get-src', b'index', b'src')) ex((bup_cmd, b'-d', b'get-src', b'tick')) # Ensure the save names differ exr = exo((bup_cmd, b'-d', b'get-src', b'save', b'-tcn', b'src', b'src')) out = exr.out.splitlines() tree_2_id = out[0] commit_2_id = out[-1] exr = exo((bup_cmd, b'-d', b'get-src', b'ls', b'src')) save_2 = exr.out.splitlines()[2] rename(b'src', b'src-2') src_root = getcwd() + b'/src' subtree_path = b'src-2/x' subtree_vfs_path = src_root + b'/x' # No support for "ls -d", so grep... exr = exo((bup_cmd, b'-d', b'get-src', b'ls', b'-s', b'src/latest' + src_root)) out = exr.out.splitlines() subtree_id = None for line in out: if b'x' in line: subtree_id = line.split()[0] assert(subtree_id) # With a tiny file, we'll get a single blob, not a chunked tree tinyfile_path = src_root + b'/tiny-file' exr = exo((bup_cmd, b'-d', b'get-src', b'ls', b'-s', b'src/latest' + tinyfile_path)) tinyfile_id = exr.out.splitlines()[0].split()[0] ex((bup_cmd, b'-d', b'get-src', b'tag', b'tinyfile', tinyfile_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'subtree', subtree_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'tree-0', tree_0_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'tree-1', tree_1_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'tree-2', tree_2_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'commit-0', commit_0_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'commit-1', commit_1_id)) ex((bup_cmd, b'-d', b'get-src', b'tag', b'commit-2', commit_2_id)) ex((b'git', b'--git-dir', b'get-src', b'branch', b'commit-1', commit_1_id)) ex((b'git', b'--git-dir', b'get-src', b'branch', b'commit-2', commit_2_id)) return {'tinyfile-path' : tinyfile_path, 'tinyfile-id' : tinyfile_id, 'subtree-id' : subtree_id, 'tree-0-id' : tree_0_id, 'tree-1-id' : tree_1_id, 'tree-2-id' : tree_2_id, 'commit-0-id' : commit_0_id, 'commit-1-id' : commit_1_id, 'commit-2-id' : commit_2_id, 'save-1' : save_1, 'save-2' : save_2, 'subtree-path' : subtree_path, 'subtree-vfs-path' : subtree_vfs_path}
def _test_new_tag(get_disposition, src_info): tinyfile_id = src_info['tinyfile-id'] tinyfile_path = src_info['tinyfile-path'] commit_2_id = src_info['commit-2-id'] tree_2_id = src_info['tree-2-id'] subtree_id = src_info['subtree-id'] subtree_vfs_path = src_info['subtree-vfs-path'] wvstart(get_disposition + ' --new-tag to root fails') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path, b'.tag/subtree', b'src/latest' + subtree_vfs_path, b'.tag/commit-1', b'src/latest', b'src'): exr = run_get(get_disposition, b'--new-tag', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'destination for .+ must be a VFS tag', exr.err) # Anything to new tag. wvstart(get_disposition + ' --new-tag, blob tag') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): exr = run_get(get_disposition, b'--new-tag', (item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_blob(tinyfile_id, tinyfile_id) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' --new-tag, tree tag') for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): exr = run_get(get_disposition, b'--new-tag', (item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_tree(subtree_id, subtree_id) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' --new-tag, committish tag') for item in (b'.tag/commit-2', b'src/latest', b'src'): exr = run_get(get_disposition, b'--new-tag', (item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_tagged_save(b'obj', getcwd() + b'/src/', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=[], tags=(b'obj',)) # Anything to existing tag (fails). for ex_type, ex_tag in (('blob', (b'.tag/tinyfile', b'.tag/obj')), ('tree', (b'.tag/tree-1', b'.tag/obj')), ('commit', (b'.tag/commit-1', b'.tag/obj'))): for item_type, item in (('blob tag', b'.tag/tinyfile'), ('blob path', b'src/latest' + tinyfile_path), ('tree tag', b'.tag/subtree'), ('tree path', b'src/latest' + subtree_vfs_path), ('commit tag', b'.tag/commit-2'), ('save', b'src/latest'), ('branch', b'src')): wvstart(get_disposition + ' --new-tag of ' + item_type + ', given existing ' + ex_type + ' tag, fails') exr = run_get(get_disposition, b'--new-tag', (item, b'.tag/obj'), given=ex_tag) wvpassne(0, exr.rc) verify_rx(br'cannot overwrite existing tag .* \(requires --replace\)', exr.err) # Anything to branch (fails). for ex_type, ex_tag in (('nothing', None), ('blob', (b'.tag/tinyfile', b'.tag/obj')), ('tree', (b'.tag/tree-1', b'.tag/obj')), ('commit', (b'.tag/commit-1', b'.tag/obj'))): for item_type, item in (('blob tag', b'.tag/tinyfile'), ('blob path', b'src/latest' + tinyfile_path), ('tree tag', b'.tag/subtree'), ('tree path', b'src/latest' + subtree_vfs_path), ('commit tag', b'.tag/commit-2'), ('save', b'src/latest'), ('branch', b'src')): wvstart(get_disposition + ' --new-tag to branch of ' + item_type + ', given existing ' + ex_type + ' tag, fails') exr = run_get(get_disposition, b'--new-tag', (item, b'obj'), given=ex_tag) wvpassne(0, exr.rc) verify_rx(br'destination for .+ must be a VFS tag', exr.err) wvstart(get_disposition + ' --new-tag, implicit destinations') exr = run_get(get_disposition, b'--new-tag', b'.tag/commit-2') wvpasseq(0, exr.rc) validate_tagged_save(b'commit-2', getcwd() + b'/src/', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=[], tags=(b'commit-2',))
def _test_pick_common(get_disposition, src_info, force=False): flavor = b'--force-pick' if force else b'--pick' flavormsg = flavor.decode('ascii') tinyfile_path = src_info['tinyfile-path'] subtree_vfs_path = src_info['subtree-vfs-path'] wvstart(get_disposition + ' ' + flavormsg + ' to root fails') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path, b'src'): exr = run_get(get_disposition, flavor, (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'can only pick a commit or save', exr.err) for item in (b'.tag/commit-1', b'src/latest'): exr = run_get(get_disposition, flavor, (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'destination is not a tag or branch', exr.err) for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): exr = run_get(get_disposition, flavor, (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'is impossible; can only --append a tree', exr.err) wvstart(get_disposition + ' ' + flavormsg + ' of blob or branch fails') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path, b'src'): for given, get_item in ((None, (item, b'obj')), (None, (item, b'.tag/obj')), ((b'.tag/tinyfile', b'.tag/obj'), (item, b'.tag/obj')), ((b'.tag/tree-1', b'.tag/obj'), (item, b'.tag/obj')), ((b'.tag/commit-1', b'.tag/obj'), (item, b'.tag/obj')), ((b'.tag/commit-1', b'obj'), (item, b'obj'))): exr = run_get(get_disposition, flavor, get_item, given=given) wvpassne(0, exr.rc) verify_rx(br'impossible; can only pick a commit or save', exr.err) wvstart(get_disposition + ' ' + flavormsg + ' of tree fails') for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): for given, get_item in ((None, (item, b'obj')), (None, (item, b'.tag/obj')), ((b'.tag/tinyfile', b'.tag/obj'), (item, b'.tag/obj')), ((b'.tag/tree-1', b'.tag/obj'), (item, b'.tag/obj')), ((b'.tag/commit-1', b'.tag/obj'), (item, b'.tag/obj')), ((b'.tag/commit-1', b'obj'), (item, b'obj'))): exr = run_get(get_disposition, flavor, get_item, given=given) wvpassne(0, exr.rc) verify_rx(br'impossible; can only --append a tree', exr.err) save_2 = src_info['save-2'] commit_2_id = src_info['commit-2-id'] tree_2_id = src_info['tree-2-id'] # FIXME: these two wvstart texts? if force: wvstart(get_disposition + ' ' + flavormsg + ' commit/save to existing tag') for item in (b'.tag/commit-2', b'src/' + save_2): for given in ((b'.tag/tinyfile', b'.tag/obj'), (b'.tag/tree-1', b'.tag/obj'), (b'.tag/commit-1', b'.tag/obj')): exr = run_get(get_disposition, flavor, (item, b'.tag/obj'), given=given) wvpasseq(0, exr.rc) validate_new_tagged_commit(b'obj', commit_2_id, tree_2_id, exr.out) verify_only_refs(heads=[], tags=(b'obj',)) else: # --pick wvstart(get_disposition + ' ' + flavormsg + ' commit/save to existing tag fails') for item in (b'.tag/commit-2', b'src/' + save_2): for given in ((b'.tag/tinyfile', b'.tag/obj'), (b'.tag/tree-1', b'.tag/obj'), (b'.tag/commit-1', b'.tag/obj')): exr = run_get(get_disposition, flavor, (item, b'.tag/obj'), given=given) wvpassne(0, exr.rc) verify_rx(br'cannot overwrite existing tag', exr.err) wvstart(get_disposition + ' ' + flavormsg + ' commit/save to tag') for item in (b'.tag/commit-2', b'src/' + save_2): exr = run_get(get_disposition, flavor, (item, b'.tag/obj')) wvpasseq(0, exr.rc) validate_clean_repo() validate_new_tagged_commit(b'obj', commit_2_id, tree_2_id, exr.out) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' ' + flavormsg + ' commit/save to branch') for item in (b'.tag/commit-2', b'src/' + save_2): for given in (None, (b'.tag/commit-1', b'obj'), (b'.tag/commit-2', b'obj')): exr = run_get(get_disposition, flavor, (item, b'obj'), given=given) wvpasseq(0, exr.rc) validate_clean_repo() validate_new_save(b'obj/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) wvstart(get_disposition + ' ' + flavormsg + ' commit/save unrelated commit to branch') for item in(b'.tag/commit-2', b'src/' + save_2): exr = run_get(get_disposition, flavor, (item, b'obj'), given=(b'unrelated-branch', b'obj')) wvpasseq(0, exr.rc) validate_clean_repo() validate_new_save(b'obj/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) wvstart(get_disposition + ' ' + flavormsg + ' commit/save ancestor to branch') save_1 = src_info['save-1'] commit_1_id = src_info['commit-1-id'] tree_1_id = src_info['tree-1-id'] for item in (b'.tag/commit-1', b'src/' + save_1): exr = run_get(get_disposition, flavor, (item, b'obj'), given=(b'.tag/commit-2', b'obj')) wvpasseq(0, exr.rc) validate_clean_repo() validate_new_save(b'obj/latest', getcwd() + b'/src', commit_1_id, tree_1_id, b'src-1', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) wvstart(get_disposition + ' ' + flavormsg + ', implicit destinations') exr = run_get(get_disposition, flavor, b'.tag/commit-2') wvpasseq(0, exr.rc) validate_clean_repo() validate_new_tagged_commit(b'commit-2', commit_2_id, tree_2_id, exr.out) verify_only_refs(heads=[], tags=(b'commit-2',)) exr = run_get(get_disposition, flavor, b'src/latest') wvpasseq(0, exr.rc) validate_clean_repo() validate_new_save(b'src/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'src',), tags=[])
def _test_append(get_disposition, src_info): tinyfile_path = src_info['tinyfile-path'] subtree_vfs_path = src_info['subtree-vfs-path'] wvstart(get_disposition + ' --append to root fails') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): exr = run_get(get_disposition, b'--append', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'source for .+ must be a branch, save, commit, or tree', exr.err) for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path, b'.tag/commit-1', b'src/latest', b'src'): exr = run_get(get_disposition, b'--append', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'destination for .+ is a root, not a branch', exr.err) wvstart(get_disposition + ' --append of not-treeish fails') for src in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): for given, item in ((None, (src, b'obj')), (None, (src, b'.tag/obj')), ((b'.tag/tinyfile', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/tree-1', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/commit-1', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/commit-1', b'obj'), (src, b'obj'))): exr = run_get(get_disposition, b'--append', item, given=given) wvpassne(0, exr.rc) verify_rx(br'must be a branch, save, commit, or tree', exr.err) wvstart(get_disposition + ' --append committish failure cases') save_2 = src_info['save-2'] for src in (b'.tag/subtree', b'src/latest' + subtree_vfs_path, b'.tag/commit-2', b'src/' + save_2, b'src'): for given, item, complaint in \ ((None, (src, b'.tag/obj'), br'destination .+ must be a valid branch name'), ((b'.tag/tinyfile', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a blob, not a branch'), ((b'.tag/tree-1', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a tree, not a branch'), ((b'.tag/commit-1', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a tagged commit, not a branch'), ((b'.tag/commit-2', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a tagged commit, not a branch')): exr = run_get(get_disposition, b'--append', item, given=given) wvpassne(0, exr.rc) verify_rx(complaint, exr.err) wvstart(get_disposition + ' --append committish') commit_2_id = src_info['commit-2-id'] tree_2_id = src_info['tree-2-id'] for item in (b'.tag/commit-2', b'src/' + save_2, b'src'): for existing in (None, (b'.tag/commit-1', b'obj'), (b'.tag/commit-2', b'obj'), (b'unrelated-branch', b'obj')): exr = run_get(get_disposition, b'--append', (item, b'obj'), given=existing) wvpasseq(0, exr.rc) validate_new_save(b'obj/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) # Append ancestor save_1 = src_info['save-1'] commit_1_id = src_info['commit-1-id'] tree_1_id = src_info['tree-1-id'] for item in (b'.tag/commit-1', b'src/' + save_1, b'src-1'): exr = run_get(get_disposition, b'--append', (item, b'obj'), given=(b'.tag/commit-2', b'obj')) wvpasseq(0, exr.rc) validate_new_save(b'obj/latest', getcwd() + b'/src', commit_1_id, tree_1_id, b'src-1', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) wvstart(get_disposition + ' --append tree') subtree_path = src_info['subtree-path'] subtree_id = src_info['subtree-id'] for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): for existing in (None, (b'.tag/commit-1', b'obj'), (b'.tag/commit-2', b'obj')): exr = run_get(get_disposition, b'--append', (item, b'obj'), given=existing) wvpasseq(0, exr.rc) validate_new_save(b'obj/latest', b'/', None, subtree_id, subtree_path, exr.out) verify_only_refs(heads=(b'obj',), tags=[]) wvstart(get_disposition + ' --append, implicit destinations') for item in (b'src', b'src/latest'): exr = run_get(get_disposition, b'--append', item) wvpasseq(0, exr.rc) validate_new_save(b'src/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'src',), tags=[])
def _test_ff(get_disposition, src_info): wvstart(get_disposition + ' --ff to root fails') tinyfile_path = src_info['tinyfile-path'] for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): exr = run_get(get_disposition, b'--ff', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'source for .+ must be a branch, save, or commit', exr.err) subtree_vfs_path = src_info['subtree-vfs-path'] for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): exr = run_get(get_disposition, b'--ff', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'is impossible; can only --append a tree to a branch', exr.err) for item in (b'.tag/commit-1', b'src/latest', b'src'): exr = run_get(get_disposition, b'--ff', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'destination for .+ is a root, not a branch', exr.err) wvstart(get_disposition + ' --ff of not-committish fails') for src in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): # FIXME: use get_item elsewhere? for given, get_item in ((None, (src, b'obj')), (None, (src, b'.tag/obj')), ((b'.tag/tinyfile', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/tree-1', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/commit-1', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/commit-1', b'obj'), (src, b'obj'))): exr = run_get(get_disposition, b'--ff', get_item, given=given) wvpassne(0, exr.rc) verify_rx(br'must be a branch, save, or commit', exr.err) for src in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): for given, get_item in ((None, (src, b'obj')), (None, (src, b'.tag/obj')), ((b'.tag/tinyfile', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/tree-1', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/commit-1', b'.tag/obj'), (src, b'.tag/obj')), ((b'.tag/commit-1', b'obj'), (src, b'obj'))): exr = run_get(get_disposition, b'--ff', get_item, given=given) wvpassne(0, exr.rc) verify_rx(br'can only --append a tree to a branch', exr.err) wvstart(get_disposition + ' --ff committish, ff possible') save_2 = src_info['save-2'] for src in (b'.tag/commit-2', b'src/' + save_2, b'src'): for given, get_item, complaint in \ ((None, (src, b'.tag/obj'), br'destination .+ must be a valid branch name'), ((b'.tag/tinyfile', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a blob, not a branch'), ((b'.tag/tree-1', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a tree, not a branch'), ((b'.tag/commit-1', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a tagged commit, not a branch'), ((b'.tag/commit-2', b'.tag/obj'), (src, b'.tag/obj'), br'destination .+ is a tagged commit, not a branch')): exr = run_get(get_disposition, b'--ff', get_item, given=given) wvpassne(0, exr.rc) verify_rx(complaint, exr.err) # FIXME: use src or item and given or existing consistently in loops... commit_2_id = src_info['commit-2-id'] tree_2_id = src_info['tree-2-id'] for src in (b'.tag/commit-2', b'src/' + save_2, b'src'): for given in (None, (b'.tag/commit-1', b'obj'), (b'.tag/commit-2', b'obj')): exr = run_get(get_disposition, b'--ff', (src, b'obj'), given=given) wvpasseq(0, exr.rc) validate_save(b'obj/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) wvstart(get_disposition + ' --ff, implicit destinations') for item in (b'src', b'src/latest'): exr = run_get(get_disposition, b'--ff', item) wvpasseq(0, exr.rc) ex((b'find', b'get-dest/refs')) ex((bup_cmd, b'-d', b'get-dest', b'ls')) validate_save(b'src/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) #verify_only_refs(heads=('src',), tags=[]) wvstart(get_disposition + ' --ff, ff impossible') for given, get_item in (((b'unrelated-branch', b'src'), b'src'), ((b'.tag/commit-2', b'src'), (b'.tag/commit-1', b'src'))): exr = run_get(get_disposition, b'--ff', get_item, given=given) wvpassne(0, exr.rc) verify_rx(br'destination is not an ancestor of source', exr.err)
def _test_replace(get_disposition, src_info): print('blarg:', repr(src_info), file=sys.stderr) wvstart(get_disposition + ' --replace to root fails') for item in (b'.tag/tinyfile', b'src/latest' + src_info['tinyfile-path'], b'.tag/subtree', b'src/latest' + src_info['subtree-vfs-path'], b'.tag/commit-1', b'src/latest', b'src'): exr = run_get(get_disposition, b'--replace', (item, b'/')) wvpassne(0, exr.rc) verify_rx(br'impossible; can only overwrite branch or tag', exr.err) tinyfile_id = src_info['tinyfile-id'] tinyfile_path = src_info['tinyfile-path'] subtree_vfs_path = src_info['subtree-vfs-path'] subtree_id = src_info['subtree-id'] commit_2_id = src_info['commit-2-id'] tree_2_id = src_info['tree-2-id'] # Anything to tag existing_items = {'nothing' : None, 'blob' : (b'.tag/tinyfile', b'.tag/obj'), 'tree' : (b'.tag/tree-1', b'.tag/obj'), 'commit': (b'.tag/commit-1', b'.tag/obj')} for ex_type, ex_ref in existing_items.items(): wvstart(get_disposition + ' --replace ' + ex_type + ' with blob tag') for item in (b'.tag/tinyfile', b'src/latest' + tinyfile_path): exr = run_get(get_disposition, b'--replace', (item ,b'.tag/obj'), given=ex_ref) wvpasseq(0, exr.rc) validate_blob(tinyfile_id, tinyfile_id) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' --replace ' + ex_type + ' with tree tag') for item in (b'.tag/subtree', b'src/latest' + subtree_vfs_path): exr = run_get(get_disposition, b'--replace', (item, b'.tag/obj'), given=ex_ref) validate_tree(subtree_id, subtree_id) verify_only_refs(heads=[], tags=(b'obj',)) wvstart(get_disposition + ' --replace ' + ex_type + ' with commitish tag') for item in (b'.tag/commit-2', b'src/latest', b'src'): exr = run_get(get_disposition, b'--replace', (item, b'.tag/obj'), given=ex_ref) validate_tagged_save(b'obj', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=[], tags=(b'obj',)) # Committish to branch. existing_items = (('nothing', None), ('branch', (b'.tag/commit-1', b'obj'))) for ex_type, ex_ref in existing_items: for item_type, item in (('commit', b'.tag/commit-2'), ('save', b'src/latest'), ('branch', b'src')): wvstart(get_disposition + ' --replace ' + ex_type + ' with ' + item_type) exr = run_get(get_disposition, b'--replace', (item, b'obj'), given=ex_ref) validate_save(b'obj/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'obj',), tags=[]) # Not committish to branch existing_items = (('nothing', None), ('branch', (b'.tag/commit-1', b'obj'))) for ex_type, ex_ref in existing_items: for item_type, item in (('blob', b'.tag/tinyfile'), ('blob', b'src/latest' + tinyfile_path), ('tree', b'.tag/subtree'), ('tree', b'src/latest' + subtree_vfs_path)): wvstart(get_disposition + ' --replace branch with ' + item_type + ' given ' + ex_type + ' fails') exr = run_get(get_disposition, b'--replace', (item, b'obj'), given=ex_ref) wvpassne(0, exr.rc) verify_rx(br'cannot overwrite branch with .+ for', exr.err) wvstart(get_disposition + ' --replace, implicit destinations') exr = run_get(get_disposition, b'--replace', b'src') validate_save(b'src/latest', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=(b'src',), tags=[]) exr = run_get(get_disposition, b'--replace', b'.tag/commit-2') validate_tagged_save(b'commit-2', getcwd() + b'/src', commit_2_id, tree_2_id, b'src-2', exr.out) verify_only_refs(heads=[], tags=(b'commit-2',))
def test_ftp(tmpdir): environ[b'BUP_DIR'] = tmpdir + b'/repo' environ[b'GIT_DIR'] = tmpdir + b'/repo' environ[b'TZ'] = b'UTC' tzset() chdir(tmpdir) mkdir(b'src') chdir(b'src') mkdir(b'dir') with open(b'file-1', 'wb') as f: f.write(b'excitement!\n') with open(b'dir/file-2', 'wb') as f: f.write(b'more excitement!\n') symlink(b'file-1', b'file-symlink') symlink(b'dir', b'dir-symlink') symlink(b'not-there', b'bad-symlink') chdir(tmpdir) bup(b'init') bup(b'index', b'src') bup(b'save', b'-n', b'src', b'--strip', b'src') save_utc = int( exo((b'git', b'show', b'-s', b'--format=%at', b'src')).out.strip()) save_name = strftime('%Y-%m-%d-%H%M%S', localtime(save_utc)).encode('ascii') wvstart('help') wvpasseq(b'Commands: ls cd pwd cat get mget help quit\n', exo((bup_cmd, b'ftp'), input=b'help\n', stderr=PIPE).out) wvstart('pwd/cd') wvpasseq(b'/\n', bup(b'ftp', input=b'pwd\n').out) wvpasseq(b'', bup(b'ftp', input=b'cd src\n').out) wvpasseq(b'/src\n', bup(b'ftp', input=jl(b'cd src', b'pwd')).out) wvpasseq(b'/src\n/\n', bup(b'ftp', input=jl(b'cd src', b'pwd', b'cd ..', b'pwd')).out) wvpasseq( b'/src\n/\n', bup(b'ftp', input=jl(b'cd src', b'pwd', b'cd ..', b'cd ..', b'pwd')).out) wvpasseq(b'/src/%s/dir\n' % save_name, bup(b'ftp', input=jl(b'cd src/latest/dir-symlink', b'pwd')).out) wvpasseq(b'/src/%s/dir\n' % save_name, bup(b'ftp', input=jl(b'cd src latest dir-symlink', b'pwd')).out) wvpassne( 0, bup(b'ftp', input=jl(b'cd src/latest/bad-symlink', b'pwd'), check=False, stdout=None).rc) wvpassne( 0, bup(b'ftp', input=jl(b'cd src/latest/not-there', b'pwd'), check=False, stdout=None).rc) wvstart('ls') # FIXME: elaborate wvpasseq(b'src\n', bup(b'ftp', input=b'ls\n').out) wvpasseq(save_name + b'\nlatest\n', bup(b'ftp', input=b'ls src\n').out) wvstart('cat') wvpasseq(b'excitement!\n', bup(b'ftp', input=b'cat src/latest/file-1\n').out) wvpasseq( b'excitement!\nmore excitement!\n', bup(b'ftp', input=b'cat src/latest/file-1 src/latest/dir/file-2\n').out) wvstart('get') bup(b'ftp', input=jl(b'get src/latest/file-1 dest')) with open(b'dest', 'rb') as f: wvpasseq(b'excitement!\n', f.read()) unlink(b'dest') bup(b'ftp', input=jl(b'get src/latest/file-symlink dest')) with open(b'dest', 'rb') as f: wvpasseq(b'excitement!\n', f.read()) unlink(b'dest') wvpassne( 0, bup(b'ftp', input=jl(b'get src/latest/bad-symlink dest'), check=False, stdout=None).rc) wvpassne( 0, bup(b'ftp', input=jl(b'get src/latest/not-there'), check=False, stdout=None).rc) wvstart('mget') unlink_if_exists(b'file-1') bup(b'ftp', input=jl(b'mget src/latest/file-1')) with open(b'file-1', 'rb') as f: wvpasseq(b'excitement!\n', f.read()) unlink_if_exists(b'file-1') unlink_if_exists(b'file-2') bup(b'ftp', input=jl(b'mget src/latest/file-1 src/latest/dir/file-2')) with open(b'file-1', 'rb') as f: wvpasseq(b'excitement!\n', f.read()) with open(b'file-2', 'rb') as f: wvpasseq(b'more excitement!\n', f.read()) unlink_if_exists(b'file-symlink') bup(b'ftp', input=jl(b'mget src/latest/file-symlink')) with open(b'file-symlink', 'rb') as f: wvpasseq(b'excitement!\n', f.read()) wvpassne( 0, bup(b'ftp', input=jl(b'mget src/latest/bad-symlink dest'), check=False, stdout=None).rc) # bup mget currently always does pattern matching bup(b'ftp', input=b'mget src/latest/not-there\n')
def test_prune_older(tmpdir): environ[b'GIT_AUTHOR_NAME'] = b'bup test' environ[b'GIT_COMMITTER_NAME'] = b'bup test' environ[b'GIT_AUTHOR_EMAIL'] = b'bup@a425bc70a02811e49bdf73ee56450e6f' environ[b'GIT_COMMITTER_EMAIL'] = b'bup@a425bc70a02811e49bdf73ee56450e6f' seed = int(environ.get(b'BUP_TEST_SEED', time())) random.seed(seed) print('random seed:', seed, file=stderr) save_population = int(environ.get(b'BUP_TEST_PRUNE_OLDER_SAVES', 2000)) prune_cycles = int(environ.get(b'BUP_TEST_PRUNE_OLDER_CYCLES', 20)) prune_gc_cycles = int(environ.get(b'BUP_TEST_PRUNE_OLDER_GC_CYCLES', 10)) bup_cmd = bup.path.exe() environ[b'BUP_DIR'] = tmpdir + b'/work/.git' environ[b'GIT_DIR'] = tmpdir + b'/work/.git' now = int(time()) three_years_ago = now - (60 * 60 * 24 * 366 * 3) chdir(tmpdir) ex([b'git', b'init', b'work']) ex([b'git', b'config', b'gc.autoDetach', b'false']) wvstart('generating ' + str(save_population) + ' random saves') chdir(tmpdir + b'/work') save_utcs = create_older_random_saves(save_population, three_years_ago, now) chdir(tmpdir) test_set_hash = exo([b'git', b'show-ref', b'-s', b'master']).out.rstrip() ls_saves = exo((bup_cmd, b'ls', b'master')).out.splitlines() wvpasseq(save_population + 1, len(ls_saves)) wvstart('ensure everything kept, if no keep arguments') ex([b'git', b'reset', b'--hard', test_set_hash]) proc = ex((bup_cmd, b'prune-older', b'-v', b'--unsafe', b'--no-gc', b'--wrt', b'%d' % now) \ + (b'master',), stdout=None, stderr=PIPE, check=False) wvpassne(proc.rc, 0) wvpass(b'at least one keep argument is required' in proc.err) check_prune_result(save_utcs) wvstart('running %d generative no-gc tests on %d saves' % (prune_cycles, save_population)) for spec in unique_period_specs(prune_cycles, # Make it more likely we'll have # some outside the save range. three_years_ago - period_scale[b'm'], now): ex([b'git', b'reset', b'--hard', test_set_hash]) expected = sorted(expected_retentions(save_utcs, now, spec)) ex((bup_cmd, b'prune-older', b'-v', b'--unsafe', b'--no-gc', b'--wrt', b'%d' % now) \ + period_spec_to_period_args(spec) \ + (b'master',)) check_prune_result(expected) # More expensive because we have to recreate the repo each time wvstart('running %d generative gc tests on %d saves' % (prune_gc_cycles, save_population)) ex([b'git', b'reset', b'--hard', test_set_hash]) copytree(b'work/.git', b'clean-test-repo', symlinks=True) for spec in unique_period_specs(prune_gc_cycles, # Make it more likely we'll have # some outside the save range. three_years_ago - period_scale[b'm'], now): rmtree(b'work/.git') copytree(b'clean-test-repo', b'work/.git') expected = sorted(expected_retentions(save_utcs, now, spec)) ex((bup_cmd, b'prune-older', b'-v', b'--unsafe', b'--wrt', b'%d' % now) \ + period_spec_to_period_args(spec) \ + (b'master',)) check_prune_result(expected)