diff --git a/tests_with_gitaly/test_repository_service.py b/tests_with_gitaly/test_repository_service.py index a696f9a2bbc7de0d63e74fd04836e4a390ff16a9_dGVzdHNfd2l0aF9naXRhbHkvdGVzdF9yZXBvc2l0b3J5X3NlcnZpY2UucHk=..8e4e08dad73fa66a9c2f87b0a43ae84b9fa205be_dGVzdHNfd2l0aF9naXRhbHkvdGVzdF9yZXBvc2l0b3J5X3NlcnZpY2UucHk= 100644 --- a/tests_with_gitaly/test_repository_service.py +++ b/tests_with_gitaly/test_repository_service.py @@ -13,6 +13,7 @@ import itertools # from hgitaly.git import EMPTY_TREE_OID from hgitaly.stub.shared_pb2 import Repository +from hgitaly import stream from hgitaly.stub.repository_service_pb2 import ( CreateRepositoryRequest, CreateBundleRequest, @@ -16,6 +17,7 @@ from hgitaly.stub.repository_service_pb2 import ( CreateRepositoryRequest, CreateBundleRequest, + CreateBundleFromRefListRequest, CreateRepositoryFromBundleRequest, FindMergeBaseRequest, SetFullPathRequest, @@ -310,3 +312,137 @@ rpc_create_repository_from_bundle('hg') assert exc_info_hg.value.code() == exc_info_git.value.code() assert exc_info_hg.value.details() == exc_info_git.value.details() + + +def test_create_bundle_from_ref_list( + gitaly_comparison, tmpdir, server_repos_root): + default_storage = 'default' + fixture = gitaly_comparison + gitaly_repo = fixture.gitaly_repo + wrapper = fixture.hg_repo_wrapper + + # repo structure: + # + # @ 3 zoo (branch:toy) (phase: draft) (amended) + # | + # | o 1 bar (branch: animal) (tag: v1.2.3) + # |/ + # o 0 foo (branch: default) + # + ctx0 = wrapper.commit_file('foo') + sha0 = ctx0.hex() + sha1 = wrapper.commit_file('bar', branch='animal').hex() + wrapper.commit_file('zoo', parent=ctx0, branch='toys').hex() + wrapper.amend_file('zoo') + wrapper.set_phase('public', [sha0, sha1]) + wrapper.update(sha1) + wrapper.command('tag', b'v1.2.3', rev=sha1) + wrapper.command('gitlab-mirror') + + def target_repo_path(vcs, bundle_name): + relative_path = '%s_%s_repo' % (vcs, bundle_name) + return server_repos_root / default_storage / relative_path + + def target_repo_msg(vcs, bundle_name): + relative_path = '%s_%s_repo' % (vcs, bundle_name) + # relative_path = vcs + bundle_name + return Repository(relative_path=relative_path, + storage_name=default_storage) + + def target_repo(vcs, bundle_name): + path = target_repo_path(vcs, bundle_name) + if vcs == 'git': + return git.GitRepo(path) + return LocalRepoWrapper.load(path).repo.unfiltered() + + def vcs_qualified_bundle_path(vcs, bundle_name): + return tmpdir / (vcs + bundle_name) + + repo_stub = dict( + hg=RepositoryServiceStub(fixture.hgitaly_channel), + git=RepositoryServiceStub(fixture.gitaly_channel), + ) + + def rpc_create_bundle_from_ref_list( + vcs, bundle_name, refs, without_repository=False): + bundle_path = vcs_qualified_bundle_path(vcs, bundle_name) + + def get_request_iter(refs): + first_req = True + for chunk in stream.split_batches(refs, 2): + if first_req and not without_repository: + first_req = False + yield CreateBundleFromRefListRequest( + repository=gitaly_repo, + patterns=chunk) + continue + yield CreateBundleFromRefListRequest(patterns=chunk) + + request = get_request_iter(refs) + response = repo_stub[vcs].CreateBundleFromRefList(request) + with open(bundle_path, 'wb') as fobj: + for chunk in response: + fobj.write(chunk.data) + + def rpc_create_repository_from_bundle(vcs, bundle_name): + bundle_path = vcs_qualified_bundle_path(vcs, bundle_name) + + def get_request_iter(data): + first_req = True + for chunk in stream.split_batches(data, 10): + if first_req: + first_req = False + yield CreateRepositoryFromBundleRequest( + repository=target_repo_msg(vcs, bundle_name), + data=chunk) + continue + yield CreateRepositoryFromBundleRequest(data=chunk) + + with open(bundle_path, 'rb') as fobj: + data = fobj.read() + request = get_request_iter(data) + return repo_stub[vcs].CreateRepositoryFromBundle(request) + + def create_bundle(bundle_name, *refs): + rpc_create_bundle_from_ref_list('hg', bundle_name, refs) + rpc_create_bundle_from_ref_list('git', bundle_name, refs) + + def create_repository_from_bundle(bundle_name): + rpc_create_repository_from_bundle('hg', bundle_name) + rpc_create_repository_from_bundle('git', bundle_name) + + def assert_compare_created_repository_from_bundle(bundle_name): + target_hgrepo = target_repo('hg', bundle_name) + target_gitrepo = target_repo('git', bundle_name) + assert_compare_hg_git_created_repos(target_hgrepo, target_gitrepo) + + # 1) test with all refs + allrefs_bundle = 'all_refs_bundle' + create_bundle( + allrefs_bundle, + b'refs/heads/branch/animal', b'refs/heads/branch/toys', + b'refs/heads/branch/default', b'refs/tags/v1.2.3') + create_repository_from_bundle(allrefs_bundle) + # test successful repo creation from bundle + assert_compare_created_repository_from_bundle(allrefs_bundle) + + # 2) test with some refs + somerefs_bundle = 'some_refs_bundle' + create_bundle( + somerefs_bundle, + b'refs/heads/branch/default', b'refs/heads/branch/toys') + create_repository_from_bundle(somerefs_bundle) + # test successful repo creation from bundle + assert_compare_created_repository_from_bundle(somerefs_bundle) + + # test error case: no repository object in request + with pytest.raises(grpc.RpcError) as exc_info_git: + rpc_create_bundle_from_ref_list( + 'git', 'temp_bname', [b'refs/heads/branch/default'], + without_repository=True) + with pytest.raises(grpc.RpcError) as exc_info_hg: + rpc_create_bundle_from_ref_list( + 'hg', 'temp_bname', [b'refs/heads/branch/default'], + without_repository=True) + assert exc_info_hg.value.code() == exc_info_git.value.code() + assert exc_info_hg.value.details() == exc_info_git.value.details()