Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/gitaly_client')
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb115
-rw-r--r--spec/lib/gitlab/gitaly_client/operation_service_spec.rb230
2 files changed, 249 insertions, 96 deletions
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index 92860c9232f..3a34d39c722 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -340,17 +340,12 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
let(:revisions) { [revision] }
let(:gitaly_commits) { create_list(:gitaly_commit, 3) }
let(:expected_commits) { gitaly_commits.map { |c| Gitlab::Git::Commit.new(repository, c) }}
- let(:filter_quarantined_commits) { false }
subject do
- client.list_new_commits(revisions, allow_quarantine: allow_quarantine)
+ client.list_new_commits(revisions)
end
shared_examples 'a #list_all_commits message' do
- before do
- stub_feature_flags(filter_quarantined_commits: filter_quarantined_commits)
- end
-
it 'sends a list_all_commits message' do
expected_repository = repository.gitaly_repository.dup
expected_repository.git_alternate_object_directories = Google::Protobuf::RepeatedField.new(:string)
@@ -360,29 +355,25 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
.with(gitaly_request_with_params(repository: expected_repository), kind_of(Hash))
.and_return([Gitaly::ListAllCommitsResponse.new(commits: gitaly_commits)])
- if filter_quarantined_commits
- # The object directory of the repository must not be set so that we
- # don't use the quarantine directory.
- objects_exist_repo = repository.gitaly_repository.dup
- objects_exist_repo.git_object_directory = ""
-
- # The first request contains the repository, the second request the
- # commit IDs we want to check for existence.
- objects_exist_request = [
- gitaly_request_with_params(repository: objects_exist_repo),
- gitaly_request_with_params(revisions: gitaly_commits.map(&:id))
- ]
-
- objects_exist_response = Gitaly::CheckObjectsExistResponse.new(revisions: revision_existence.map do
- |rev, exists| Gitaly::CheckObjectsExistResponse::RevisionExistence.new(name: rev, exists: exists)
- end)
-
- expect(service).to receive(:check_objects_exist)
- .with(objects_exist_request, kind_of(Hash))
- .and_return([objects_exist_response])
- else
- expect(service).not_to receive(:check_objects_exist)
- end
+ # The object directory of the repository must not be set so that we
+ # don't use the quarantine directory.
+ objects_exist_repo = repository.gitaly_repository.dup
+ objects_exist_repo.git_object_directory = ""
+
+ # The first request contains the repository, the second request the
+ # commit IDs we want to check for existence.
+ objects_exist_request = [
+ gitaly_request_with_params(repository: objects_exist_repo),
+ gitaly_request_with_params(revisions: gitaly_commits.map(&:id))
+ ]
+
+ objects_exist_response = Gitaly::CheckObjectsExistResponse.new(revisions: revision_existence.map do
+ |rev, exists| Gitaly::CheckObjectsExistResponse::RevisionExistence.new(name: rev, exists: exists)
+ end)
+
+ expect(service).to receive(:check_objects_exist)
+ .with(objects_exist_request, kind_of(Hash))
+ .and_return([objects_exist_response])
end
expect(subject).to eq(expected_commits)
@@ -418,49 +409,31 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
}
end
- context 'with allowed quarantine' do
- let(:allow_quarantine) { true }
-
- context 'without commit filtering' do
- it_behaves_like 'a #list_all_commits message'
- end
-
- context 'with commit filtering' do
- let(:filter_quarantined_commits) { true }
-
- context 'reject commits which exist in target repository' do
- let(:revision_existence) { gitaly_commits.to_h { |c| [c.id, true] } }
- let(:expected_commits) { [] }
-
- it_behaves_like 'a #list_all_commits message'
- end
-
- context 'keep commits which do not exist in target repository' do
- let(:revision_existence) { gitaly_commits.to_h { |c| [c.id, false] } }
+ context 'reject commits which exist in target repository' do
+ let(:revision_existence) { gitaly_commits.to_h { |c| [c.id, true] } }
+ let(:expected_commits) { [] }
- it_behaves_like 'a #list_all_commits message'
- end
+ it_behaves_like 'a #list_all_commits message'
+ end
- context 'mixed existing and nonexisting commits' do
- let(:revision_existence) do
- {
- gitaly_commits[0].id => true,
- gitaly_commits[1].id => false,
- gitaly_commits[2].id => true
- }
- end
+ context 'keep commits which do not exist in target repository' do
+ let(:revision_existence) { gitaly_commits.to_h { |c| [c.id, false] } }
- let(:expected_commits) { [Gitlab::Git::Commit.new(repository, gitaly_commits[1])] }
+ it_behaves_like 'a #list_all_commits message'
+ end
- it_behaves_like 'a #list_all_commits message'
- end
+ context 'mixed existing and nonexisting commits' do
+ let(:revision_existence) do
+ {
+ gitaly_commits[0].id => true,
+ gitaly_commits[1].id => false,
+ gitaly_commits[2].id => true
+ }
end
- end
- context 'with disallowed quarantine' do
- let(:allow_quarantine) { false }
+ let(:expected_commits) { [Gitlab::Git::Commit.new(repository, gitaly_commits[1])] }
- it_behaves_like 'a #list_commits message'
+ it_behaves_like 'a #list_all_commits message'
end
end
@@ -472,17 +445,7 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
}
end
- context 'with allowed quarantine' do
- let(:allow_quarantine) { true }
-
- it_behaves_like 'a #list_commits message'
- end
-
- context 'with disallowed quarantine' do
- let(:allow_quarantine) { false }
-
- it_behaves_like 'a #list_commits message'
- end
+ it_behaves_like 'a #list_commits message'
end
end
diff --git a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
index 0c04863f466..4320c5460da 100644
--- a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
@@ -170,6 +170,65 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
Gitlab::Git::PreReceiveError, "something failed")
end
end
+
+ context 'with a custom hook error' do
+ let(:stdout) { nil }
+ let(:stderr) { nil }
+ let(:error_message) { "error_message" }
+ let(:custom_hook_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::PERMISSION_DENIED,
+ error_message,
+ Gitaly::UserDeleteBranchError.new(
+ custom_hook: Gitaly::CustomHookError.new(
+ stdout: stdout,
+ stderr: stderr,
+ hook_type: Gitaly::CustomHookError::HookType::HOOK_TYPE_PRERECEIVE
+ )))
+ end
+
+ shared_examples 'a failed branch deletion' do
+ it 'raises a PreRecieveError' do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_delete_branch).with(request, kind_of(Hash))
+ .and_raise(custom_hook_error)
+
+ expect { subject }.to raise_error do |error|
+ expect(error).to be_a(Gitlab::Git::PreReceiveError)
+ expect(error.message).to eq(expected_message)
+ expect(error.raw_message).to eq(expected_raw_message)
+ end
+ end
+ end
+
+ context 'when details contain stderr' do
+ let(:stderr) { "something" }
+ let(:stdout) { "GL-HOOK-ERR: stdout is overridden by stderr" }
+ let(:expected_message) { error_message }
+ let(:expected_raw_message) { stderr }
+
+ it_behaves_like 'a failed branch deletion'
+ end
+
+ context 'when details contain stdout' do
+ let(:stderr) { " \n" }
+ let(:stdout) { "something" }
+ let(:expected_message) { error_message }
+ let(:expected_raw_message) { stdout }
+
+ it_behaves_like 'a failed branch deletion'
+ end
+ end
+
+ context 'with a non-detailed error' do
+ it 'raises a GRPC error' do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_delete_branch).with(request, kind_of(Hash))
+ .and_raise(GRPC::Internal.new('non-detailed error'))
+
+ expect { subject }.to raise_error(GRPC::Internal)
+ end
+ end
end
describe '#user_merge_branch' do
@@ -212,6 +271,82 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
end
end
+ context 'with a custom hook error' do
+ let(:stdout) { nil }
+ let(:stderr) { nil }
+ let(:error_message) { "error_message" }
+ let(:custom_hook_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::PERMISSION_DENIED,
+ error_message,
+ Gitaly::UserMergeBranchError.new(
+ custom_hook: Gitaly::CustomHookError.new(
+ stdout: stdout,
+ stderr: stderr,
+ hook_type: Gitaly::CustomHookError::HookType::HOOK_TYPE_PRERECEIVE
+ )))
+ end
+
+ shared_examples 'a failed merge' do
+ it 'raises a PreRecieveError' do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_merge_branch).with(kind_of(Enumerator), kind_of(Hash))
+ .and_raise(custom_hook_error)
+
+ expect { subject }.to raise_error do |error|
+ expect(error).to be_a(Gitlab::Git::PreReceiveError)
+ expect(error.message).to eq(expected_message)
+ expect(error.raw_message).to eq(expected_raw_message)
+ end
+ end
+ end
+
+ context 'when details contain stderr without prefix' do
+ let(:stderr) { "something" }
+ let(:stdout) { "GL-HOOK-ERR: stdout is overridden by stderr" }
+ let(:expected_message) { error_message }
+ let(:expected_raw_message) { stderr }
+
+ it_behaves_like 'a failed merge'
+ end
+
+ context 'when details contain stderr with prefix' do
+ let(:stderr) { "GL-HOOK-ERR: something" }
+ let(:stdout) { "GL-HOOK-ERR: stdout is overridden by stderr" }
+ let(:expected_message) { "something" }
+ let(:expected_raw_message) { stderr }
+
+ it_behaves_like 'a failed merge'
+ end
+
+ context 'when details contain stdout without prefix' do
+ let(:stderr) { " \n" }
+ let(:stdout) { "something" }
+ let(:expected_message) { error_message }
+ let(:expected_raw_message) { stdout }
+
+ it_behaves_like 'a failed merge'
+ end
+
+ context 'when details contain stdout with prefix' do
+ let(:stderr) { " \n" }
+ let(:stdout) { "GL-HOOK-ERR: something" }
+ let(:expected_message) { "something" }
+ let(:expected_raw_message) { stdout }
+
+ it_behaves_like 'a failed merge'
+ end
+
+ context 'when details contain no stderr or stdout' do
+ let(:stderr) { " \n" }
+ let(:stdout) { "\n \n" }
+ let(:expected_message) { error_message }
+ let(:expected_raw_message) { "\n \n" }
+
+ it_behaves_like 'a failed merge'
+ end
+ end
+
context 'with an exception without the detailed error' do
let(:permission_error) do
GRPC::PermissionDenied.new
@@ -340,6 +475,15 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
end
end
+ shared_examples '#user_cherry_pick with a gRPC error' do
+ it 'raises an exception' do
+ expect_any_instance_of(Gitaly::OperationService::Stub).to receive(:user_cherry_pick)
+ .and_raise(raised_error)
+
+ expect { subject }.to raise_error(expected_error, expected_error_message)
+ end
+ end
+
describe '#user_cherry_pick' do
let(:response_class) { Gitaly::UserCherryPickResponse }
@@ -354,13 +498,74 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
)
end
- before do
- expect_any_instance_of(Gitaly::OperationService::Stub)
- .to receive(:user_cherry_pick).with(kind_of(Gitaly::UserCherryPickRequest), kind_of(Hash))
- .and_return(response)
+ context 'when errors are not raised but returned in the response' do
+ before do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_cherry_pick).with(kind_of(Gitaly::UserCherryPickRequest), kind_of(Hash))
+ .and_return(response)
+ end
+
+ it_behaves_like 'cherry pick and revert errors'
end
- it_behaves_like 'cherry pick and revert errors'
+ context 'when AccessCheckError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::INTERNAL,
+ 'something failed',
+ Gitaly::UserCherryPickError.new(
+ access_check: Gitaly::AccessCheckError.new(
+ error_message: 'something went wrong'
+ )))
+ end
+
+ let(:expected_error) { Gitlab::Git::PreReceiveError }
+ let(:expected_error_message) { "something went wrong" }
+
+ it_behaves_like '#user_cherry_pick with a gRPC error'
+ end
+
+ context 'when NotAncestorError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::FAILED_PRECONDITION,
+ 'Branch diverged',
+ Gitaly::UserCherryPickError.new(
+ target_branch_diverged: Gitaly::NotAncestorError.new
+ )
+ )
+ end
+
+ let(:expected_error) { Gitlab::Git::CommitError }
+ let(:expected_error_message) { 'branch diverged' }
+
+ it_behaves_like '#user_cherry_pick with a gRPC error'
+ end
+
+ context 'when MergeConflictError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::FAILED_PRECONDITION,
+ 'Conflict',
+ Gitaly::UserCherryPickError.new(
+ cherry_pick_conflict: Gitaly::MergeConflictError.new
+ )
+ )
+ end
+
+ let(:expected_error) { Gitlab::Git::Repository::CreateTreeError }
+ let(:expected_error_message) { }
+
+ it_behaves_like '#user_cherry_pick with a gRPC error'
+ end
+
+ context 'when a non-detailed gRPC error is raised' do
+ let(:raised_error) { GRPC::Internal.new('non-detailed error') }
+ let(:expected_error) { GRPC::Internal }
+ let(:expected_error_message) { }
+
+ it_behaves_like '#user_cherry_pick with a gRPC error'
+ end
end
describe '#user_revert' do
@@ -489,21 +694,6 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
expect(subject).to eq(squash_sha)
end
- context "when git_error is present" do
- let(:response) do
- Gitaly::UserSquashResponse.new(git_error: "something failed")
- end
-
- it "raises a GitError exception" do
- expect_any_instance_of(Gitaly::OperationService::Stub)
- .to receive(:user_squash).with(request, kind_of(Hash))
- .and_return(response)
-
- expect { subject }.to raise_error(
- Gitlab::Git::Repository::GitError, "something failed")
- end
- end
-
shared_examples '#user_squash with an error' do
it 'raises a GitError exception' do
expect_any_instance_of(Gitaly::OperationService::Stub)