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/with_feature_flag_actors_spec.rb')
-rw-r--r--spec/lib/gitlab/gitaly_client/with_feature_flag_actors_spec.rb275
1 files changed, 275 insertions, 0 deletions
diff --git a/spec/lib/gitlab/gitaly_client/with_feature_flag_actors_spec.rb b/spec/lib/gitlab/gitaly_client/with_feature_flag_actors_spec.rb
new file mode 100644
index 00000000000..41dce5d76dd
--- /dev/null
+++ b/spec/lib/gitlab/gitaly_client/with_feature_flag_actors_spec.rb
@@ -0,0 +1,275 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GitalyClient::WithFeatureFlagActors do
+ let(:user) { create(:user) }
+ let(:service) do
+ Class.new do
+ include Gitlab::GitalyClient::WithFeatureFlagActors
+ end.new
+ end
+
+ describe '#user_actor' do
+ context 'when user is not available in ApplicationContext' do
+ it 'returns nil' do
+ expect(service.user_actor).to be(nil)
+ end
+ end
+
+ context 'when user is available in ApplicationContext' do
+ around do |example|
+ ::Gitlab::ApplicationContext.with_context(user: user) { example.run }
+ end
+
+ it 'returns corresponding user record' do
+ expect(service.user_actor.flipper_id).to eql(user.flipper_id)
+ end
+ end
+
+ context 'when user does not exist' do
+ around do |example|
+ ::Gitlab::ApplicationContext.with_context(user: SecureRandom.uuid) { example.run }
+ end
+
+ it 'returns corresponding user record' do
+ expect(service.user_actor).to be(nil)
+ end
+ end
+ end
+
+ describe '#repository, #project_actor, #group_actor' do
+ context 'when normal project repository' do
+ let_it_be(:project) { create(:project, group: create(:group)) }
+ let(:expected_project) { project }
+ let(:expected_group) { Feature::Gitaly::ActorWrapper.new(::Group, project.group.id) }
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { project.repository }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { project.repository.raw }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { raw_repo_without_container(project.repository) }
+ end
+ end
+
+ context 'when project wiki repository' do
+ let_it_be(:project) { create(:project, :wiki_repo, group: create(:group)) }
+ let(:expected_project) { nil }
+ let(:expected_group) { nil }
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { project.wiki.repository }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { project.wiki.repository.raw }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { raw_repo_without_container(project.wiki.repository) }
+ end
+ end
+
+ context 'when repository of project in user namespace' do
+ let_it_be(:project) { create(:project, namespace: create(:user).namespace) }
+ let(:expected_project) { project }
+ let(:expected_group) { Feature::Gitaly::ActorWrapper.new(::Group, project.namespace_id) }
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { project.repository }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { project.repository.raw }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { raw_repo_without_container(project.repository) }
+ end
+ end
+
+ context 'when personal snippet' do
+ let(:snippet) { create(:personal_snippet) }
+ let(:expected_project) { nil }
+ let(:expected_group) { nil }
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { snippet.repository }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { snippet.repository.raw }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { raw_repo_without_container(snippet.repository) }
+ end
+ end
+
+ context 'when project snippet' do
+ let_it_be(:project) { create(:project, group: create(:group)) }
+ let(:snippet) { create(:project_snippet, project: project) }
+ let(:expected_project) { nil }
+ let(:expected_group) { nil }
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { snippet.repository }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { snippet.repository.raw }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { raw_repo_without_container(snippet.repository) }
+ end
+ end
+
+ context 'when project design' do
+ let_it_be(:project) { create(:project, group: create(:group)) }
+ let(:issue) { create(:issue, project: project) }
+ let(:design) { create(:design, issue: issue) }
+
+ let(:expected_project) { project }
+ let(:expected_group) { project.group }
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { design.repository }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { design.repository.raw }
+ end
+
+ it_behaves_like 'Gitaly feature flag actors are inferred from repository' do
+ let(:repository) { raw_repo_without_container(design.repository) }
+ end
+ end
+ end
+
+ describe '#gitaly_client_call' do
+ let(:call_arg_1) { double }
+ let(:call_arg_2) { double }
+ let(:call_arg_3) { double }
+ let(:call_result) { double }
+
+ before do
+ allow(Gitlab::GitalyClient).to receive(:call).and_return(call_result)
+ end
+
+ context 'when actors_aware_gitaly_calls flag is enabled' do
+ let(:repository_actor) { instance_double(::Repository) }
+ let(:user_actor) { instance_double(::User) }
+ let(:project_actor) { instance_double(Project) }
+ let(:group_actor) { instance_double(Group) }
+
+ before do
+ stub_feature_flags(actors_aware_gitaly_calls: true)
+
+ allow(service).to receive(:user_actor).and_return(user_actor)
+ allow(service).to receive(:repository_actor).and_return(repository_actor)
+ allow(service).to receive(:project_actor).and_return(project_actor)
+ allow(service).to receive(:group_actor).and_return(group_actor)
+ allow(Gitlab::GitalyClient).to receive(:with_feature_flag_actors).and_call_original
+ end
+
+ it 'triggers client call with feature flag actors' do
+ result = service.gitaly_client_call(call_arg_1, call_arg_2, karg: call_arg_3)
+
+ expect(Gitlab::GitalyClient).to have_received(:call).with(call_arg_1, call_arg_2, karg: call_arg_3)
+ expect(Gitlab::GitalyClient).to have_received(:with_feature_flag_actors).with(
+ repository: repository_actor,
+ user: user_actor,
+ project: project_actor,
+ group: group_actor
+ )
+ expect(result).to be(call_result)
+ end
+
+ context 'when call without repository_actor' do
+ before do
+ allow(service).to receive(:repository_actor).and_return(nil)
+ allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).and_call_original
+ end
+
+ it 'calls error tracking track_and_raise_for_dev_exception' do
+ expect do
+ service.gitaly_client_call(call_arg_1, call_arg_2, karg: call_arg_3)
+ end.to raise_error /gitaly_client_call called without setting repository_actor/
+
+ expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_for_dev_exception).with(
+ be_a(Feature::InvalidFeatureFlagError)
+ )
+ end
+ end
+ end
+
+ context 'when actors_aware_gitaly_calls not enabled' do
+ before do
+ stub_feature_flags(actors_aware_gitaly_calls: false)
+ end
+
+ it 'triggers client call without feature flag actors' do
+ expect(Gitlab::GitalyClient).not_to receive(:with_feature_flag_actors)
+
+ result = service.gitaly_client_call(call_arg_1, call_arg_2, karg: call_arg_3)
+
+ expect(Gitlab::GitalyClient).to have_received(:call).with(call_arg_1, call_arg_2, karg: call_arg_3)
+ expect(result).to be(call_result)
+ end
+ end
+
+ describe '#gitaly_feature_flag_actors' do
+ let_it_be(:project) { create(:project) }
+ let(:repository_actor) { project.repository }
+
+ context 'when actors_aware_gitaly_calls flag is enabled' do
+ let(:user_actor) { instance_double(::User) }
+ let(:project_actor) { instance_double(Project) }
+ let(:group_actor) { instance_double(Group) }
+
+ before do
+ stub_feature_flags(actors_aware_gitaly_calls: true)
+
+ allow(Feature::Gitaly).to receive(:user_actor).and_return(user_actor)
+ allow(Feature::Gitaly).to receive(:project_actor).with(project).and_return(project_actor)
+ allow(Feature::Gitaly).to receive(:group_actor).with(project).and_return(group_actor)
+ end
+
+ it 'returns a hash with collected feature flag actors' do
+ result = service.gitaly_feature_flag_actors(repository_actor)
+ expect(result).to eql(
+ repository: repository_actor,
+ user: user_actor,
+ project: project_actor,
+ group: group_actor
+ )
+
+ expect(Feature::Gitaly).to have_received(:user_actor).with(no_args)
+ expect(Feature::Gitaly).to have_received(:project_actor).with(project)
+ expect(Feature::Gitaly).to have_received(:group_actor).with(project)
+ end
+ end
+
+ context 'when actors_aware_gitaly_calls not enabled' do
+ before do
+ stub_feature_flags(actors_aware_gitaly_calls: false)
+ end
+
+ it 'returns an empty hash' do
+ expect(Feature::Gitaly).not_to receive(:user_actor)
+ expect(Feature::Gitaly).not_to receive(:project_actor)
+ expect(Feature::Gitaly).not_to receive(:group_actor)
+
+ result = service.gitaly_feature_flag_actors(repository_actor)
+ expect(result).to eql({})
+ end
+ end
+ end
+ end
+end