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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-13 12:09:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-13 12:09:58 +0300
commitda12067d6bb2603f40d2de107df70e2ff03630e8 (patch)
tree7d5fcdce8e53a4f491d9a6a81826ffef3589cf83 /spec
parente9626c2383e1bbf325a302bb840891c3c7b8cb07 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb12
-rw-r--r--spec/lib/gitlab/search_results_spec.rb4
-rw-r--r--spec/services/git/branch_push_service_spec.rb20
-rw-r--r--spec/services/git/process_ref_changes_service_spec.rb6
-rw-r--r--spec/support/database/ci_tables.rb22
-rw-r--r--spec/support/database/prevent_cross_database_modification.rb120
-rw-r--r--spec/support/database/prevent_cross_joins.rb19
-rw-r--r--spec/support_specs/database/prevent_cross_database_modification_spec.rb144
-rw-r--r--spec/views/search/show.html.haml_spec.rb49
-rw-r--r--spec/workers/jira_connect/forward_event_worker_spec.rb22
-rw-r--r--spec/workers/jira_connect/retry_request_worker_spec.rb45
-rw-r--r--spec/workers/post_receive_spec.rb48
12 files changed, 433 insertions, 78 deletions
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index 49f1e6e994f..f58bab52cfa 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -369,11 +369,15 @@ RSpec.describe Gitlab::Git::Commit, :seed_helper do
commits.map { |c| c.id }
end
- it 'has 1 element' do
- expect(subject.size).to eq(1)
+ it { is_expected.to contain_exactly(SeedRepo::Commit::ID) }
+
+ context 'between_uses_list_commits FF disabled' do
+ before do
+ stub_feature_flags(between_uses_list_commits: false)
+ end
+
+ it { is_expected.to contain_exactly(SeedRepo::Commit::ID) }
end
- it { is_expected.to include(SeedRepo::Commit::ID) }
- it { is_expected.not_to include(SeedRepo::FirstCommit::ID) }
end
describe '.shas_with_signatures' do
diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb
index 2974893ec4a..b8972f28889 100644
--- a/spec/lib/gitlab/search_results_spec.rb
+++ b/spec/lib/gitlab/search_results_spec.rb
@@ -33,6 +33,10 @@ RSpec.describe Gitlab::SearchResults do
expect(results.objects('projects', page: 1, per_page: 1, without_count: false)).not_to be_kind_of(Kaminari::PaginatableWithoutCount)
end
+ it 'returns without counts collection when requested' do
+ expect(results.objects('projects', page: 1, per_page: 1, without_count: true)).to be_kind_of(Kaminari::PaginatableWithoutCount)
+ end
+
it 'uses page and per_page to paginate results' do
project2 = create(:project, name: 'foo')
diff --git a/spec/services/git/branch_push_service_spec.rb b/spec/services/git/branch_push_service_spec.rb
index cc691833ef3..d70e458ba5e 100644
--- a/spec/services/git/branch_push_service_spec.rb
+++ b/spec/services/git/branch_push_service_spec.rb
@@ -151,9 +151,9 @@ RSpec.describe Git::BranchPushService, services: true do
it "when pushing a new branch for the first time" do
expect(UpdateMergeRequestsWorker)
.to receive(:perform_async)
- .with(project.id, user.id, blankrev, 'newrev', ref)
+ .with(project.id, user.id, blankrev, newrev, ref)
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
end
end
@@ -162,13 +162,13 @@ RSpec.describe Git::BranchPushService, services: true do
it "calls the copy attributes method for the first push to the default branch" do
expect(project.repository).to receive(:copy_gitattributes).with('master')
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
end
it "calls the copy attributes method for changes to the default branch" do
expect(project.repository).to receive(:copy_gitattributes).with(ref)
- execute_service(project, user, oldrev: 'oldrev', newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end
end
@@ -195,7 +195,7 @@ RSpec.describe Git::BranchPushService, services: true do
it "when pushing a branch for the first time" do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
@@ -206,7 +206,7 @@ RSpec.describe Git::BranchPushService, services: true do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
expect(project.protected_branches).to be_empty
end
@@ -216,7 +216,7 @@ RSpec.describe Git::BranchPushService, services: true do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
@@ -231,7 +231,7 @@ RSpec.describe Git::BranchPushService, services: true do
expect(project.default_branch).to eq("master")
expect(ProtectedBranches::CreateService).not_to receive(:new)
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::NO_ACCESS])
@@ -243,7 +243,7 @@ RSpec.describe Git::BranchPushService, services: true do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, oldrev: blankrev, newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: blankrev, newrev: newrev, ref: ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
@@ -251,7 +251,7 @@ RSpec.describe Git::BranchPushService, services: true do
it "when pushing new commits to existing branch" do
expect(project).to receive(:execute_hooks)
- execute_service(project, user, oldrev: 'oldrev', newrev: 'newrev', ref: ref)
+ execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end
end
end
diff --git a/spec/services/git/process_ref_changes_service_spec.rb b/spec/services/git/process_ref_changes_service_spec.rb
index ac9bac4e6ad..2a223091d0c 100644
--- a/spec/services/git/process_ref_changes_service_spec.rb
+++ b/spec/services/git/process_ref_changes_service_spec.rb
@@ -116,6 +116,8 @@ RSpec.describe Git::ProcessRefChangesService do
if changes_method == :tag_changes
allow_any_instance_of(Repository).to receive(:tag_exists?) { true }
end
+
+ allow(Gitlab::Git::Commit).to receive(:between) { [] }
end
context 'when git_push_create_all_pipelines is disabled' do
@@ -150,6 +152,8 @@ RSpec.describe Git::ProcessRefChangesService do
context 'with invalid .gitlab-ci.yml' do
before do
stub_ci_pipeline_yaml_file(nil)
+
+ allow(Gitlab::Git::Commit).to receive(:between) { [] }
end
it 'does not create a pipeline' do
@@ -190,6 +194,8 @@ RSpec.describe Git::ProcessRefChangesService do
allow(MergeRequests::PushedBranchesService).to receive(:new).and_return(
double(execute: %w(create1 create2)), double(execute: %w(changed1)), double(execute: %w(removed2))
)
+
+ allow(Gitlab::Git::Commit).to receive(:between).and_return([])
end
it 'schedules job for existing merge requests' do
diff --git a/spec/support/database/ci_tables.rb b/spec/support/database/ci_tables.rb
new file mode 100644
index 00000000000..99fc7ac2501
--- /dev/null
+++ b/spec/support/database/ci_tables.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+# This module stores the CI-related database tables which are
+# going to be moved to a separate database.
+module Database
+ module CiTables
+ def self.include?(name)
+ ci_tables.include?(name)
+ end
+
+ def self.ci_tables
+ @@ci_tables ||= Set.new.tap do |tables| # rubocop:disable Style/ClassVars
+ tables.merge(Ci::ApplicationRecord.descendants.map(&:table_name).compact)
+
+ # It was decided that taggings/tags are best placed with CI
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/333413
+ tables.add('taggings')
+ tables.add('tags')
+ end
+ end
+ end
+end
diff --git a/spec/support/database/prevent_cross_database_modification.rb b/spec/support/database/prevent_cross_database_modification.rb
new file mode 100644
index 00000000000..47202696dfd
--- /dev/null
+++ b/spec/support/database/prevent_cross_database_modification.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+module Database
+ module PreventCrossDatabaseModification
+ CrossDatabaseModificationAcrossUnsupportedTablesError = Class.new(StandardError)
+
+ module GitlabDatabaseMixin
+ def allow_cross_database_modification_within_transaction(url:)
+ return yield unless Thread.current[:transaction_tracker]
+
+ cross_database_context = Database::PreventCrossDatabaseModification.cross_database_context
+ return yield unless cross_database_context[:enabled]
+
+ transaction_tracker_enabled_was = cross_database_context[:enabled]
+ cross_database_context[:enabled] = false
+
+ yield
+ ensure
+ cross_database_context[:enabled] = transaction_tracker_enabled_was if Thread.current[:transaction_tracker]
+ end
+ end
+
+ module SpecHelpers
+ def with_cross_database_modification_prevented
+ subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |name, start, finish, id, payload|
+ PreventCrossDatabaseModification.prevent_cross_database_modification!(payload[:connection], payload[:sql])
+ end
+
+ PreventCrossDatabaseModification.reset_cross_database_context!
+ PreventCrossDatabaseModification.cross_database_context.merge!(enabled: true, subscriber: subscriber)
+
+ yield if block_given?
+ ensure
+ cleanup_with_cross_database_modification_prevented if block_given?
+ end
+
+ def cleanup_with_cross_database_modification_prevented
+ ActiveSupport::Notifications.unsubscribe(PreventCrossDatabaseModification.cross_database_context[:subscriber])
+ PreventCrossDatabaseModification.cross_database_context[:enabled] = false
+ end
+ end
+
+ def self.cross_database_context
+ Thread.current[:transaction_tracker] ||= initial_data
+ end
+
+ def self.reset_cross_database_context!
+ Thread.current[:transaction_tracker] = initial_data
+ end
+
+ def self.initial_data
+ {
+ enabled: false,
+ transaction_depth_by_db: Hash.new { |h, k| h[k] = 0 },
+ modified_tables_by_db: Hash.new { |h, k| h[k] = Set.new }
+ }
+ end
+
+ def self.prevent_cross_database_modification!(connection, sql)
+ return unless cross_database_context[:enabled]
+
+ database = connection.pool.db_config.name
+
+ if sql.start_with?('SAVEPOINT')
+ cross_database_context[:transaction_depth_by_db][database] += 1
+
+ return
+ elsif sql.start_with?('RELEASE SAVEPOINT', 'ROLLBACK TO SAVEPOINT')
+ cross_database_context[:transaction_depth_by_db][database] -= 1
+ if cross_database_context[:transaction_depth_by_db][database] <= 0
+ cross_database_context[:modified_tables_by_db][database].clear
+ end
+
+ return
+ end
+
+ return if cross_database_context[:transaction_depth_by_db].values.all?(&:zero?)
+
+ tables = PgQuery.parse(sql).dml_tables
+
+ return if tables.empty?
+
+ cross_database_context[:modified_tables_by_db][database].merge(tables)
+
+ ci_table_referenced = false
+ main_table_referenced = false
+ all_tables = cross_database_context[:modified_tables_by_db].values.map(&:to_a).flatten
+ all_tables.each do |table|
+ if Database::CiTables.include?(table)
+ ci_table_referenced = true
+ else
+ main_table_referenced = true
+ end
+ end
+
+ if ci_table_referenced && main_table_referenced
+ raise Database::PreventCrossDatabaseModification::CrossDatabaseModificationAcrossUnsupportedTablesError,
+ "Cross-database data modification queries (CI and Main) were detected within " \
+ "a transaction '#{all_tables.join(", ")}' discovered"
+ end
+ end
+ end
+end
+
+Gitlab::Database.singleton_class.prepend(
+ Database::PreventCrossDatabaseModification::GitlabDatabaseMixin)
+
+RSpec.configure do |config|
+ config.include(::Database::PreventCrossDatabaseModification::SpecHelpers)
+
+ # Using before and after blocks because the around block causes problems with the let_it_be
+ # record creations. It makes an extra savepoint which breaks the transaction count logic.
+ config.before(:each, :prevent_cross_database_modification) do
+ with_cross_database_modification_prevented
+ end
+
+ config.after(:each, :prevent_cross_database_modification) do
+ cleanup_with_cross_database_modification_prevented
+ end
+end
diff --git a/spec/support/database/prevent_cross_joins.rb b/spec/support/database/prevent_cross_joins.rb
index c49b165c6c3..789721ccd38 100644
--- a/spec/support/database/prevent_cross_joins.rb
+++ b/spec/support/database/prevent_cross_joins.rb
@@ -37,23 +37,8 @@ module Database
# Returns true if a set includes only CI tables, or includes only non-CI tables
def self.only_ci_or_only_main?(tables)
- tables.all? { |table| ci_table_name?(table) } ||
- tables.none? { |table| ci_table_name?(table) }
- end
-
- def self.ci_table_name?(name)
- ci_tables.include?(name)
- end
-
- def self.ci_tables
- @@ci_tables ||= Set.new.tap do |tables| # rubocop:disable Style/ClassVars
- tables.merge(Ci::ApplicationRecord.descendants.map(&:table_name).compact)
-
- # It was decided that taggings/tags are best placed with CI
- # https://gitlab.com/gitlab-org/gitlab/-/issues/333413
- tables.add('taggings')
- tables.add('tags')
- end
+ tables.all? { |table| CiTables.include?(table) } ||
+ tables.none? { |table| CiTables.include?(table) }
end
module SpecHelpers
diff --git a/spec/support_specs/database/prevent_cross_database_modification_spec.rb b/spec/support_specs/database/prevent_cross_database_modification_spec.rb
new file mode 100644
index 00000000000..4fd55d59db0
--- /dev/null
+++ b/spec/support_specs/database/prevent_cross_database_modification_spec.rb
@@ -0,0 +1,144 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Database::PreventCrossDatabaseModification' do
+ let_it_be(:pipeline, refind: true) { create(:ci_pipeline) }
+ let_it_be(:project, refind: true) { create(:project) }
+
+ shared_examples 'succeessful examples' do
+ context 'outside transaction' do
+ it { expect { run_queries }.not_to raise_error }
+ end
+
+ context 'within transaction' do
+ it do
+ Project.transaction do
+ expect { run_queries }.not_to raise_error
+ end
+ end
+ end
+
+ context 'within nested transaction' do
+ it do
+ Project.transaction(requires_new: true) do
+ Project.transaction(requires_new: true) do
+ expect { run_queries }.not_to raise_error
+ end
+ end
+ end
+ end
+ end
+
+ context 'when CI and other tables are read in a transaction' do
+ def run_queries
+ pipeline.reload
+ project.reload
+ end
+
+ include_examples 'succeessful examples'
+ end
+
+ context 'when only CI data is modified' do
+ def run_queries
+ pipeline.touch
+ project.reload
+ end
+
+ include_examples 'succeessful examples'
+ end
+
+ context 'when other data is modified' do
+ def run_queries
+ pipeline.reload
+ project.touch
+ end
+
+ include_examples 'succeessful examples'
+ end
+
+ describe 'with_cross_database_modification_prevented block' do
+ it 'raises error when CI and other data is modified' do
+ expect do
+ with_cross_database_modification_prevented do
+ Project.transaction do
+ project.touch
+ pipeline.touch
+ end
+ end
+ end.to raise_error /Cross-database data modification queries/
+ end
+ end
+
+ context 'when running tests with prevent_cross_database_modification', :prevent_cross_database_modification do
+ context 'when both CI and other data is modified' do
+ def run_queries
+ project.touch
+ pipeline.touch
+ end
+
+ context 'outside transaction' do
+ it { expect { run_queries }.not_to raise_error }
+ end
+
+ context 'when data modification happens in a transaction' do
+ it 'raises error' do
+ Project.transaction do
+ expect { run_queries }.to raise_error /Cross-database data modification queries/
+ end
+ end
+
+ context 'when data modification happens in nested transactions' do
+ it 'raises error' do
+ Project.transaction(requires_new: true) do
+ project.touch
+ Project.transaction(requires_new: true) do
+ expect { pipeline.touch }.to raise_error /Cross-database data modification queries/
+ end
+ end
+ end
+ end
+ end
+ end
+
+ context 'when CI association is modified through project' do
+ def run_queries
+ project.variables.build(key: 'a', value: 'v')
+ project.save!
+ end
+
+ include_examples 'succeessful examples'
+ end
+
+ describe '#allow_cross_database_modification_within_transaction' do
+ it 'skips raising error' do
+ expect do
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'gitlab-issue') do
+ Project.transaction do
+ pipeline.touch
+ project.touch
+ end
+ end
+ end.not_to raise_error
+ end
+
+ it 'raises error when complex factories are built referencing both databases' do
+ expect do
+ ApplicationRecord.transaction do
+ create(:ci_pipeline)
+ end
+ end.to raise_error /Cross-database data modification queries/
+ end
+
+ it 'skips raising error on factory creation' do
+ expect do
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'gitlab-issue') do
+ ApplicationRecord.transaction do
+ create(:ci_pipeline)
+ end
+ end
+ end.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/views/search/show.html.haml_spec.rb b/spec/views/search/show.html.haml_spec.rb
index eb763d424d3..a336ec91ff2 100644
--- a/spec/views/search/show.html.haml_spec.rb
+++ b/spec/views/search/show.html.haml_spec.rb
@@ -48,21 +48,50 @@ RSpec.describe 'search/show' do
assign(:group, group)
end
- it 'renders meta tags for a group' do
- render
+ context 'search with full count' do
+ before do
+ assign(:without_count, false)
+ end
+
+ it 'renders meta tags for a group' do
+ render
+
+ expect(view.page_description).to match(/\d+ issues for term '#{search_term}'/)
+ expect(view.page_card_attributes).to eq("Namespace" => group.full_path)
+ end
- expect(view.page_description).to match(/\d+ issues for term '#{search_term}'/)
- expect(view.page_card_attributes).to eq("Namespace" => group.full_path)
+ it 'renders meta tags for both group and project' do
+ project = build(:project, group: group)
+ assign(:project, project)
+
+ render
+
+ expect(view.page_description).to match(/\d+ issues for term '#{search_term}'/)
+ expect(view.page_card_attributes).to eq("Namespace" => group.full_path, "Project" => project.full_path)
+ end
end
- it 'renders meta tags for both group and project' do
- project = build(:project, group: group)
- assign(:project, project)
+ context 'search without full count' do
+ before do
+ assign(:without_count, true)
+ end
+
+ it 'renders meta tags for a group' do
+ render
+
+ expect(view.page_description).to match(/issues results for term '#{search_term}'/)
+ expect(view.page_card_attributes).to eq("Namespace" => group.full_path)
+ end
+
+ it 'renders meta tags for both group and project' do
+ project = build(:project, group: group)
+ assign(:project, project)
- render
+ render
- expect(view.page_description).to match(/\d+ issues for term '#{search_term}'/)
- expect(view.page_card_attributes).to eq("Namespace" => group.full_path, "Project" => project.full_path)
+ expect(view.page_description).to match(/issues results for term '#{search_term}'/)
+ expect(view.page_card_attributes).to eq("Namespace" => group.full_path, "Project" => project.full_path)
+ end
end
end
end
diff --git a/spec/workers/jira_connect/forward_event_worker_spec.rb b/spec/workers/jira_connect/forward_event_worker_spec.rb
index adfc071779a..7de9952a1da 100644
--- a/spec/workers/jira_connect/forward_event_worker_spec.rb
+++ b/spec/workers/jira_connect/forward_event_worker_spec.rb
@@ -15,23 +15,23 @@ RSpec.describe JiraConnect::ForwardEventWorker do
let(:client_key) { '123' }
let(:shared_secret) { '123' }
- subject { described_class.new.perform(jira_connect_installation.id, base_path, event_path) }
+ subject(:perform) { described_class.new.perform(jira_connect_installation.id, base_path, event_path) }
- it 'forwards the event including the auth header and deletes the installation' do
+ it 'forwards the event and deletes the installation' do
stub_request(:post, event_url)
expect(Atlassian::Jwt).to receive(:create_query_string_hash).with(event_url, 'POST', base_url).and_return('some_qsh')
expect(Atlassian::Jwt).to receive(:encode).with({ iss: client_key, qsh: 'some_qsh' }, shared_secret).and_return('auth_token')
- expect { subject }.to change(JiraConnectInstallation, :count).by(-1)
+ expect(JiraConnect::RetryRequestWorker).to receive(:perform_async).with(event_url, 'auth_token')
- expect(WebMock).to have_requested(:post, event_url).with(headers: { 'Authorization' => 'JWT auth_token' })
+ expect { perform }.to change(JiraConnectInstallation, :count).by(-1)
end
context 'when installation does not exist' do
let(:jira_connect_installation) { instance_double(JiraConnectInstallation, id: -1) }
it 'does nothing' do
- expect { subject }.not_to change(JiraConnectInstallation, :count)
+ expect { perform }.not_to change(JiraConnectInstallation, :count)
end
end
@@ -39,17 +39,9 @@ RSpec.describe JiraConnect::ForwardEventWorker do
let!(:jira_connect_installation) { create(:jira_connect_installation) }
it 'forwards the event including the auth header' do
- expect { subject }.to change(JiraConnectInstallation, :count).by(-1)
+ expect { perform }.to change(JiraConnectInstallation, :count).by(-1)
- expect(WebMock).not_to have_requested(:post, '*')
- end
- end
-
- context 'when it fails to forward the event' do
- it 'still deletes the installation' do
- allow(Gitlab::HTTP).to receive(:post).and_raise(StandardError)
-
- expect { subject }.to raise_error(StandardError).and change(JiraConnectInstallation, :count).by(-1)
+ expect(JiraConnect::RetryRequestWorker).not_to receive(:perform_async)
end
end
end
diff --git a/spec/workers/jira_connect/retry_request_worker_spec.rb b/spec/workers/jira_connect/retry_request_worker_spec.rb
new file mode 100644
index 00000000000..7a93e5fe41d
--- /dev/null
+++ b/spec/workers/jira_connect/retry_request_worker_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe JiraConnect::RetryRequestWorker do
+ describe '#perform' do
+ let(:jwt) { 'some-jwt' }
+ let(:event_url) { 'https://example.com/somewhere' }
+ let(:attempts) { 3 }
+
+ subject(:perform) { described_class.new.perform(event_url, jwt, attempts) }
+
+ it 'sends the request, with the appropriate headers' do
+ expect(JiraConnect::RetryRequestWorker).not_to receive(:perform_in)
+
+ stub_request(:post, event_url)
+
+ perform
+
+ expect(WebMock).to have_requested(:post, event_url).with(headers: { 'Authorization' => 'JWT some-jwt' })
+ end
+
+ context 'when the proxied request fails' do
+ before do
+ stub_request(:post, event_url).to_return(status: 500, body: '', headers: {})
+ end
+
+ it 'arranges to retry the request' do
+ expect(JiraConnect::RetryRequestWorker).to receive(:perform_in).with(1.hour, event_url, jwt, attempts - 1)
+
+ perform
+ end
+
+ context 'when there are no more attempts left' do
+ let(:attempts) { 0 }
+
+ it 'does not retry' do
+ expect(JiraConnect::RetryRequestWorker).not_to receive(:perform_in)
+
+ perform
+ end
+ end
+ end
+ end
+end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index f26b3668653..c111c3164eb 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -5,7 +5,13 @@ require 'spec_helper'
RSpec.describe PostReceive do
include AfterNextHelpers
- let(:changes) { "123456 789012 refs/heads/tést\n654321 210987 refs/tags/tag" }
+ let(:changes) do
+ <<~EOF
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag
+ EOF
+ end
+
let(:wrongly_encoded_changes) { changes.encode("ISO-8859-1").force_encoding("UTF-8") }
let(:base64_changes) { Base64.encode64(wrongly_encoded_changes) }
let(:gl_repository) { "project-#{project.id}" }
@@ -64,7 +70,6 @@ RSpec.describe PostReceive do
describe '#process_project_changes' do
context 'with an empty project' do
let(:empty_project) { create(:project, :empty_repo) }
- let(:changes) { "123456 789012 refs/heads/tést1\n" }
before do
allow_next(Gitlab::GitPostReceive).to receive(:identify).and_return(empty_project.owner)
@@ -146,8 +151,8 @@ RSpec.describe PostReceive do
context 'branches' do
let(:changes) do
<<~EOF
- 123456 789012 refs/heads/tést1
- 123456 789012 refs/heads/tést2
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést1
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést2
EOF
end
@@ -182,9 +187,9 @@ RSpec.describe PostReceive do
context 'with a default branch' do
let(:changes) do
<<~EOF
- 123456 789012 refs/heads/tést1
- 123456 789012 refs/heads/tést2
- 678912 123455 refs/heads/#{project.default_branch}
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést1
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést2
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/#{project.default_branch}
EOF
end
@@ -200,9 +205,9 @@ RSpec.describe PostReceive do
context 'tags' do
let(:changes) do
<<~EOF
- 654321 210987 refs/tags/tag1
- 654322 210986 refs/tags/tag2
- 654323 210985 refs/tags/tag3
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag1
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag2
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag3
EOF
end
@@ -241,7 +246,7 @@ RSpec.describe PostReceive do
end
context 'merge-requests' do
- let(:changes) { "123456 789012 refs/merge-requests/123" }
+ let(:changes) { "#{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/merge-requests/123" }
it "does not call any of the services" do
expect(Git::ProcessRefChangesService).not_to receive(:new)
@@ -253,7 +258,6 @@ RSpec.describe PostReceive do
end
context 'after project changes hooks' do
- let(:changes) { '123456 789012 refs/heads/tést' }
let(:fake_hook_data) { { event_name: 'repository_update' } }
before do
@@ -305,12 +309,12 @@ RSpec.describe PostReceive do
context 'master' do
let(:default_branch) { 'master' }
- let(:oldrev) { '012345' }
- let(:newrev) { '6789ab' }
+ let(:oldrev) { SeedRepo::Commit::PARENT_ID }
+ let(:newrev) { SeedRepo::Commit::ID }
let(:changes) do
<<~EOF
#{oldrev} #{newrev} refs/heads/#{default_branch}
- 123456 789012 refs/heads/tést2
+ #{oldrev} #{newrev} refs/heads/tést2
EOF
end
@@ -326,8 +330,8 @@ RSpec.describe PostReceive do
context 'branches' do
let(:changes) do
<<~EOF
- 123456 789012 refs/heads/tést1
- 123456 789012 refs/heads/tést2
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést1
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést2
EOF
end
@@ -406,8 +410,8 @@ RSpec.describe PostReceive do
context 'branches' do
let(:changes) do
<<~EOF
- 123456 789012 refs/heads/tést1
- 123456 789012 refs/heads/tést2
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést1
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/heads/tést2
EOF
end
@@ -434,9 +438,9 @@ RSpec.describe PostReceive do
context 'tags' do
let(:changes) do
<<~EOF
- 654321 210987 refs/tags/tag1
- 654322 210986 refs/tags/tag2
- 654323 210985 refs/tags/tag3
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag1
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag2
+ #{SeedRepo::Commit::PARENT_ID} #{SeedRepo::Commit::ID} refs/tags/tag3
EOF
end