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/workers')
-rw-r--r--spec/workers/analytics/instance_statistics/counter_job_worker_spec.rb20
-rw-r--r--spec/workers/authorized_project_update/periodic_recalculate_worker_spec.rb12
-rw-r--r--spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb12
-rw-r--r--spec/workers/cleanup_container_repository_worker_spec.rb23
-rw-r--r--spec/workers/concerns/limited_capacity/job_tracker_spec.rb100
-rw-r--r--spec/workers/concerns/limited_capacity/worker_spec.rb285
-rw-r--r--spec/workers/design_management/copy_design_collection_worker_spec.rb39
-rw-r--r--spec/workers/design_management/new_version_worker_spec.rb4
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb50
-rw-r--r--spec/workers/group_import_worker_spec.rb53
-rw-r--r--spec/workers/incident_management/add_severity_system_note_worker_spec.rb60
-rw-r--r--spec/workers/incident_management/process_alert_worker_spec.rb2
-rw-r--r--spec/workers/incident_management/process_prometheus_alert_worker_spec.rb2
-rw-r--r--spec/workers/member_invitation_reminder_emails_worker_spec.rb29
-rw-r--r--spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb25
-rw-r--r--spec/workers/post_receive_spec.rb2
-rw-r--r--spec/workers/propagate_integration_group_worker_spec.rb37
-rw-r--r--spec/workers/propagate_integration_inherit_worker_spec.rb38
-rw-r--r--spec/workers/propagate_integration_project_worker_spec.rb37
19 files changed, 726 insertions, 104 deletions
diff --git a/spec/workers/analytics/instance_statistics/counter_job_worker_spec.rb b/spec/workers/analytics/instance_statistics/counter_job_worker_spec.rb
index 8db86071dc4..667ec0bcb75 100644
--- a/spec/workers/analytics/instance_statistics/counter_job_worker_spec.rb
+++ b/spec/workers/analytics/instance_statistics/counter_job_worker_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Analytics::InstanceStatistics::CounterJobWorker do
it 'counts a scope and stores the result' do
subject
- measurement = Analytics::InstanceStatistics::Measurement.first
+ measurement = Analytics::InstanceStatistics::Measurement.users.first
expect(measurement.recorded_at).to be_like_time(recorded_at)
expect(measurement.identifier).to eq('users')
expect(measurement.count).to eq(2)
@@ -33,7 +33,7 @@ RSpec.describe Analytics::InstanceStatistics::CounterJobWorker do
it 'sets 0 as the count' do
subject
- measurement = Analytics::InstanceStatistics::Measurement.first
+ measurement = Analytics::InstanceStatistics::Measurement.groups.first
expect(measurement.recorded_at).to be_like_time(recorded_at)
expect(measurement.identifier).to eq('groups')
expect(measurement.count).to eq(0)
@@ -51,4 +51,20 @@ RSpec.describe Analytics::InstanceStatistics::CounterJobWorker do
expect { subject }.not_to change { Analytics::InstanceStatistics::Measurement.count }
end
+
+ context 'when pipelines_succeeded identifier is passed' do
+ let_it_be(:pipeline) { create(:ci_pipeline, :success) }
+
+ let(:successful_pipelines_measurement_identifier) { ::Analytics::InstanceStatistics::Measurement.identifiers.fetch(:pipelines_succeeded) }
+ let(:job_args) { [successful_pipelines_measurement_identifier, pipeline.id, pipeline.id, recorded_at] }
+
+ it 'counts successful pipelines' do
+ subject
+
+ measurement = Analytics::InstanceStatistics::Measurement.pipelines_succeeded.first
+ expect(measurement.recorded_at).to be_like_time(recorded_at)
+ expect(measurement.identifier).to eq('pipelines_succeeded')
+ expect(measurement.count).to eq(1)
+ end
+ end
end
diff --git a/spec/workers/authorized_project_update/periodic_recalculate_worker_spec.rb b/spec/workers/authorized_project_update/periodic_recalculate_worker_spec.rb
index 2d633828ae3..9d4d48d0568 100644
--- a/spec/workers/authorized_project_update/periodic_recalculate_worker_spec.rb
+++ b/spec/workers/authorized_project_update/periodic_recalculate_worker_spec.rb
@@ -11,17 +11,5 @@ RSpec.describe AuthorizedProjectUpdate::PeriodicRecalculateWorker do
subject.perform
end
-
- context 'feature flag :periodic_project_authorization_recalculation is disabled' do
- before do
- stub_feature_flags(periodic_project_authorization_recalculation: false)
- end
-
- it 'does not call AuthorizedProjectUpdate::PeriodicRecalculateService' do
- expect(AuthorizedProjectUpdate::PeriodicRecalculateService).not_to receive(:new)
-
- subject.perform
- end
- end
end
end
diff --git a/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb b/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb
index c49e4c453bf..a27c431523e 100644
--- a/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb
+++ b/spec/workers/authorized_project_update/user_refresh_over_user_range_worker_spec.rb
@@ -14,17 +14,5 @@ RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
subject.perform(start_user_id, end_user_id)
end
-
- context 'feature flag :periodic_project_authorization_recalculation is disabled' do
- before do
- stub_feature_flags(periodic_project_authorization_recalculation: false)
- end
-
- it 'does not call AuthorizedProjectUpdate::RecalculateForUserRangeService' do
- expect(AuthorizedProjectUpdate::RecalculateForUserRangeService).not_to receive(:new)
-
- subject.perform(start_user_id, end_user_id)
- end
- end
end
end
diff --git a/spec/workers/cleanup_container_repository_worker_spec.rb b/spec/workers/cleanup_container_repository_worker_spec.rb
index 0545f7a35e4..9cf8974a2a1 100644
--- a/spec/workers/cleanup_container_repository_worker_spec.rb
+++ b/spec/workers/cleanup_container_repository_worker_spec.rb
@@ -40,14 +40,35 @@ RSpec.describe CleanupContainerRepositoryWorker, :clean_gitlab_redis_shared_stat
context 'container expiration policy' do
let(:params) { { key: 'value', 'container_expiration_policy' => true } }
+ before do
+ allow(ContainerRepository)
+ .to receive(:find_by_id).with(repository.id).and_return(repository)
+ end
+
it 'executes the destroy service' do
+ expect(repository).to receive(:start_expiration_policy!).and_call_original
+ expect(repository).to receive(:reset_expiration_policy_started_at!).and_call_original
expect(Projects::ContainerRepository::CleanupTagsService).to receive(:new)
.with(project, nil, params.merge('container_expiration_policy' => true))
.and_return(service)
- expect(service).to receive(:execute)
+ expect(service).to receive(:execute).and_return(status: :success)
+
+ subject.perform(nil, repository.id, params)
+ expect(repository.reload.expiration_policy_started_at).to be_nil
+ end
+
+ it "doesn't reset the expiration policy started at if the destroy service returns an error" do
+ expect(repository).to receive(:start_expiration_policy!).and_call_original
+ expect(repository).not_to receive(:reset_expiration_policy_started_at!)
+ expect(Projects::ContainerRepository::CleanupTagsService).to receive(:new)
+ .with(project, nil, params.merge('container_expiration_policy' => true))
+ .and_return(service)
+
+ expect(service).to receive(:execute).and_return(status: :error, message: 'timeout while deleting tags')
subject.perform(nil, repository.id, params)
+ expect(repository.reload.expiration_policy_started_at).not_to be_nil
end
end
end
diff --git a/spec/workers/concerns/limited_capacity/job_tracker_spec.rb b/spec/workers/concerns/limited_capacity/job_tracker_spec.rb
new file mode 100644
index 00000000000..2c79f347903
--- /dev/null
+++ b/spec/workers/concerns/limited_capacity/job_tracker_spec.rb
@@ -0,0 +1,100 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe LimitedCapacity::JobTracker, :clean_gitlab_redis_queues do
+ let(:job_tracker) do
+ described_class.new('namespace')
+ end
+
+ describe '#register' do
+ it 'adds jid to the set' do
+ job_tracker.register('a-job-id')
+
+ expect(job_tracker.running_jids).to contain_exactly('a-job-id')
+ end
+
+ it 'updates the counter' do
+ expect { job_tracker.register('a-job-id') }
+ .to change { job_tracker.count }
+ .from(0)
+ .to(1)
+ end
+
+ it 'does it in only one Redis call' do
+ expect(job_tracker).to receive(:with_redis).once.and_call_original
+
+ job_tracker.register('a-job-id')
+ end
+ end
+
+ describe '#remove' do
+ before do
+ job_tracker.register(%w[a-job-id other-job-id])
+ end
+
+ it 'removes jid from the set' do
+ job_tracker.remove('other-job-id')
+
+ expect(job_tracker.running_jids).to contain_exactly('a-job-id')
+ end
+
+ it 'updates the counter' do
+ expect { job_tracker.remove('other-job-id') }
+ .to change { job_tracker.count }
+ .from(2)
+ .to(1)
+ end
+
+ it 'does it in only one Redis call' do
+ expect(job_tracker).to receive(:with_redis).once.and_call_original
+
+ job_tracker.remove('other-job-id')
+ end
+ end
+
+ describe '#clean_up' do
+ before do
+ job_tracker.register('a-job-id')
+ end
+
+ context 'with running jobs' do
+ before do
+ expect(Gitlab::SidekiqStatus).to receive(:completed_jids)
+ .with(%w[a-job-id])
+ .and_return([])
+ end
+
+ it 'does not remove the jid from the set' do
+ expect { job_tracker.clean_up }
+ .not_to change { job_tracker.running_jids.include?('a-job-id') }
+ end
+
+ it 'does only one Redis call to get the job ids' do
+ expect(job_tracker).to receive(:with_redis).once.and_call_original
+
+ job_tracker.clean_up
+ end
+ end
+
+ context 'with completed jobs' do
+ it 'removes the jid from the set' do
+ expect { job_tracker.clean_up }
+ .to change { job_tracker.running_jids.include?('a-job-id') }
+ end
+
+ it 'updates the counter' do
+ expect { job_tracker.clean_up }
+ .to change { job_tracker.count }
+ .from(1)
+ .to(0)
+ end
+
+ it 'gets the job ids, removes them, and updates the counter with only two Redis calls' do
+ expect(job_tracker).to receive(:with_redis).twice.and_call_original
+
+ job_tracker.clean_up
+ end
+ end
+ end
+end
diff --git a/spec/workers/concerns/limited_capacity/worker_spec.rb b/spec/workers/concerns/limited_capacity/worker_spec.rb
new file mode 100644
index 00000000000..8a15675c04d
--- /dev/null
+++ b/spec/workers/concerns/limited_capacity/worker_spec.rb
@@ -0,0 +1,285 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe LimitedCapacity::Worker, :clean_gitlab_redis_queues, :aggregate_failures do
+ let(:worker_class) do
+ Class.new do
+ def self.name
+ 'DummyWorker'
+ end
+
+ include ApplicationWorker
+ include LimitedCapacity::Worker
+ end
+ end
+
+ let(:worker) { worker_class.new }
+
+ let(:job_tracker) do
+ LimitedCapacity::JobTracker.new(worker_class.name)
+ end
+
+ before do
+ worker.jid = 'my-jid'
+ allow(worker).to receive(:job_tracker).and_return(job_tracker)
+ end
+
+ describe 'required methods' do
+ it { expect { worker.perform_work }.to raise_error(NotImplementedError) }
+ it { expect { worker.remaining_work_count }.to raise_error(NotImplementedError) }
+ it { expect { worker.max_running_jobs }.to raise_error(NotImplementedError) }
+ end
+
+ describe 'Sidekiq options' do
+ it 'does not retry failed jobs' do
+ expect(worker_class.sidekiq_options['retry']).to eq(0)
+ end
+
+ it 'does not deduplicate jobs' do
+ expect(worker_class.get_deduplicate_strategy).to eq(:none)
+ end
+ end
+
+ describe '.perform_with_capacity' do
+ subject(:perform_with_capacity) { worker_class.perform_with_capacity(:arg) }
+
+ before do
+ expect_next_instance_of(worker_class) do |instance|
+ expect(instance).to receive(:remove_failed_jobs)
+ expect(instance).to receive(:report_prometheus_metrics)
+
+ allow(instance).to receive(:remaining_work_count).and_return(remaining_work_count)
+ allow(instance).to receive(:remaining_capacity).and_return(remaining_capacity)
+ end
+ end
+
+ context 'when capacity is larger than work' do
+ let(:remaining_work_count) { 2 }
+ let(:remaining_capacity) { 3 }
+
+ it 'enqueues jobs for remaining work' do
+ expect(worker_class)
+ .to receive(:bulk_perform_async)
+ .with([[:arg], [:arg]])
+
+ perform_with_capacity
+ end
+ end
+
+ context 'when capacity is lower than work' do
+ let(:remaining_work_count) { 5 }
+ let(:remaining_capacity) { 3 }
+
+ it 'enqueues jobs for remaining work' do
+ expect(worker_class)
+ .to receive(:bulk_perform_async)
+ .with([[:arg], [:arg], [:arg]])
+
+ perform_with_capacity
+ end
+ end
+ end
+
+ describe '#perform' do
+ subject(:perform) { worker.perform(:arg) }
+
+ context 'with capacity' do
+ before do
+ allow(worker).to receive(:max_running_jobs).and_return(10)
+ allow(worker).to receive(:running_jobs_count).and_return(0)
+ allow(worker).to receive(:remaining_work_count).and_return(0)
+ end
+
+ it 'calls perform_work' do
+ expect(worker).to receive(:perform_work).with(:arg)
+
+ perform
+ end
+
+ it 're-enqueues itself' do
+ allow(worker).to receive(:perform_work)
+ expect(worker).to receive(:re_enqueue).with(:arg)
+
+ perform
+ end
+
+ it 'registers itself in the running set' do
+ allow(worker).to receive(:perform_work)
+ expect(job_tracker).to receive(:register).with('my-jid')
+
+ perform
+ end
+
+ it 'removes itself from the running set' do
+ expect(job_tracker).to receive(:remove).with('my-jid')
+
+ allow(worker).to receive(:perform_work)
+
+ perform
+ end
+
+ it 'reports prometheus metrics' do
+ allow(worker).to receive(:perform_work)
+ expect(worker).to receive(:report_prometheus_metrics)
+
+ perform
+ end
+ end
+
+ context 'with capacity and without work' do
+ before do
+ allow(worker).to receive(:max_running_jobs).and_return(10)
+ allow(worker).to receive(:running_jobs_count).and_return(0)
+ allow(worker).to receive(:remaining_work_count).and_return(0)
+ allow(worker).to receive(:perform_work)
+ end
+
+ it 'does not re-enqueue itself' do
+ expect(worker_class).not_to receive(:perform_async)
+
+ perform
+ end
+ end
+
+ context 'without capacity' do
+ before do
+ allow(worker).to receive(:max_running_jobs).and_return(10)
+ allow(worker).to receive(:running_jobs_count).and_return(15)
+ allow(worker).to receive(:remaining_work_count).and_return(10)
+ end
+
+ it 'does not call perform_work' do
+ expect(worker).not_to receive(:perform_work)
+
+ perform
+ end
+
+ it 'does not re-enqueue itself' do
+ expect(worker_class).not_to receive(:perform_async)
+
+ perform
+ end
+
+ it 'does not register in the running set' do
+ expect(job_tracker).not_to receive(:register)
+
+ perform
+ end
+
+ it 'removes itself from the running set' do
+ expect(job_tracker).to receive(:remove).with('my-jid')
+
+ perform
+ end
+
+ it 'reports prometheus metrics' do
+ expect(worker).to receive(:report_prometheus_metrics)
+
+ perform
+ end
+ end
+
+ context 'when perform_work fails' do
+ it 'does not re-enqueue itself' do
+ expect(worker).not_to receive(:re_enqueue)
+
+ expect { perform }.to raise_error(NotImplementedError)
+ end
+
+ it 'removes itself from the running set' do
+ expect(job_tracker).to receive(:remove)
+
+ expect { perform }.to raise_error(NotImplementedError)
+ end
+
+ it 'reports prometheus metrics' do
+ expect(worker).to receive(:report_prometheus_metrics)
+
+ expect { perform }.to raise_error(NotImplementedError)
+ end
+ end
+ end
+
+ describe '#remaining_capacity' do
+ subject(:remaining_capacity) { worker.remaining_capacity }
+
+ before do
+ expect(worker).to receive(:max_running_jobs).and_return(max_capacity)
+ end
+
+ context 'when changing the capacity to a lower value' do
+ let(:max_capacity) { -1 }
+
+ it { expect(remaining_capacity).to eq(0) }
+ end
+
+ context 'when registering new jobs' do
+ let(:max_capacity) { 2 }
+
+ before do
+ job_tracker.register('a-job-id')
+ end
+
+ it { expect(remaining_capacity).to eq(1) }
+ end
+
+ context 'with jobs in the queue' do
+ let(:max_capacity) { 2 }
+
+ before do
+ expect(worker_class).to receive(:queue_size).and_return(1)
+ end
+
+ it { expect(remaining_capacity).to eq(1) }
+ end
+
+ context 'with both running jobs and queued jobs' do
+ let(:max_capacity) { 10 }
+
+ before do
+ expect(worker_class).to receive(:queue_size).and_return(5)
+ expect(worker).to receive(:running_jobs_count).and_return(3)
+ end
+
+ it { expect(remaining_capacity).to eq(2) }
+ end
+ end
+
+ describe '#remove_failed_jobs' do
+ subject(:remove_failed_jobs) { worker.remove_failed_jobs }
+
+ before do
+ job_tracker.register('a-job-id')
+ allow(worker).to receive(:max_running_jobs).and_return(2)
+
+ expect(job_tracker).to receive(:clean_up).and_call_original
+ end
+
+ context 'with failed jobs' do
+ it 'update the available capacity' do
+ expect { remove_failed_jobs }.to change { worker.remaining_capacity }.by(1)
+ end
+ end
+ end
+
+ describe '#report_prometheus_metrics' do
+ subject(:report_prometheus_metrics) { worker.report_prometheus_metrics }
+
+ before do
+ allow(worker).to receive(:running_jobs_count).and_return(5)
+ allow(worker).to receive(:max_running_jobs).and_return(7)
+ allow(worker).to receive(:remaining_work_count).and_return(9)
+ end
+
+ it 'reports number of running jobs' do
+ labels = { worker: 'DummyWorker' }
+
+ report_prometheus_metrics
+
+ expect(Gitlab::Metrics.registry.get(:limited_capacity_worker_running_jobs).get(labels)).to eq(5)
+ expect(Gitlab::Metrics.registry.get(:limited_capacity_worker_max_running_jobs).get(labels)).to eq(7)
+ expect(Gitlab::Metrics.registry.get(:limited_capacity_worker_remaining_work_count).get(labels)).to eq(9)
+ end
+ end
+end
diff --git a/spec/workers/design_management/copy_design_collection_worker_spec.rb b/spec/workers/design_management/copy_design_collection_worker_spec.rb
new file mode 100644
index 00000000000..45bfc47ca7e
--- /dev/null
+++ b/spec/workers/design_management/copy_design_collection_worker_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe DesignManagement::CopyDesignCollectionWorker, :clean_gitlab_redis_shared_state do
+ describe '#perform' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:target_issue) { create(:issue) }
+
+ subject { described_class.new.perform(user.id, issue.id, target_issue.id) }
+
+ it_behaves_like 'an idempotent worker' do
+ let(:job_args) { [user.id, issue.id, target_issue.id] }
+
+ specify { subject }
+ end
+
+ it 'calls DesignManagement::CopyDesignCollection::CopyService' do
+ expect_next_instance_of(DesignManagement::CopyDesignCollection::CopyService) do |service|
+ expect(service).to receive(:execute).and_return(ServiceResponse.success)
+ end
+
+ subject
+ end
+
+ it 'logs if there was an error calling the service' do
+ message = 'Error message'
+
+ allow_next_instance_of(DesignManagement::CopyDesignCollection::CopyService) do |service|
+ allow(service).to receive(:execute).and_return(ServiceResponse.error(message: message))
+ end
+
+ expect(Gitlab::AppLogger).to receive(:warn).with(message)
+
+ subject
+ end
+ end
+end
diff --git a/spec/workers/design_management/new_version_worker_spec.rb b/spec/workers/design_management/new_version_worker_spec.rb
index 4d57c46487e..3320d7a062d 100644
--- a/spec/workers/design_management/new_version_worker_spec.rb
+++ b/spec/workers/design_management/new_version_worker_spec.rb
@@ -36,6 +36,10 @@ RSpec.describe DesignManagement::NewVersionWorker do
expect { worker.perform(version.id) }.to change { Note.system.count }.by(1)
end
+ it 'does not create a system note if skip_system_notes is true' do
+ expect { worker.perform(version.id, true) }.not_to change { Note.system.count }
+ end
+
it 'invokes GenerateImageVersionsService' do
expect_next_instance_of(DesignManagement::GenerateImageVersionsService) do |service|
expect(service).to receive(:execute)
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index 1be6e86b650..018971e288c 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -129,46 +129,36 @@ RSpec.describe GitGarbageCollectWorker do
let_it_be(:lfs_reference) { create(:lfs_objects_project, project: project) }
let(:lfs_object) { lfs_reference.lfs_object }
- context 'with cleanup_lfs_during_gc feature flag enabled' do
- before do
- stub_feature_flags(cleanup_lfs_during_gc: true)
+ it 'cleans up unreferenced LFS objects' do
+ expect_next_instance_of(Gitlab::Cleanup::OrphanLfsFileReferences) do |svc|
+ expect(svc.project).to eq(project)
+ expect(svc.dry_run).to be_falsy
+ expect(svc).to receive(:run!).and_call_original
end
- it 'cleans up unreferenced LFS objects' do
- expect_next_instance_of(Gitlab::Cleanup::OrphanLfsFileReferences) do |svc|
- expect(svc.project).to eq(project)
- expect(svc.dry_run).to be_falsy
- expect(svc).to receive(:run!).and_call_original
- end
-
- subject.perform(*params)
-
- expect(project.lfs_objects.reload).not_to include(lfs_object)
- end
+ subject.perform(*params)
- it 'does nothing if the database is read-only' do
- allow(Gitlab::Database).to receive(:read_only?) { true }
+ expect(project.lfs_objects.reload).not_to include(lfs_object)
+ end
- expect_any_instance_of(Gitlab::Cleanup::OrphanLfsFileReferences).not_to receive(:run!)
+ it 'catches and logs exceptions' do
+ expect_any_instance_of(Gitlab::Cleanup::OrphanLfsFileReferences)
+ .to receive(:run!)
+ .and_raise(/Failed/)
- subject.perform(*params)
+ expect(Gitlab::GitLogger).to receive(:warn)
+ expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
- expect(project.lfs_objects.reload).to include(lfs_object)
- end
+ subject.perform(*params)
end
- context 'with cleanup_lfs_during_gc feature flag disabled' do
- before do
- stub_feature_flags(cleanup_lfs_during_gc: false)
- end
-
- it 'does not clean up unreferenced LFS objects' do
- expect_any_instance_of(Gitlab::Cleanup::OrphanLfsFileReferences).not_to receive(:run!)
+ it 'does nothing if the database is read-only' do
+ allow(Gitlab::Database).to receive(:read_only?) { true }
+ expect_any_instance_of(Gitlab::Cleanup::OrphanLfsFileReferences).not_to receive(:run!)
- subject.perform(*params)
+ subject.perform(*params)
- expect(project.lfs_objects.reload).to include(lfs_object)
- end
+ expect(project.lfs_objects.reload).to include(lfs_object)
end
end
end
diff --git a/spec/workers/group_import_worker_spec.rb b/spec/workers/group_import_worker_spec.rb
index fb2d49c21af..3fa24ecd7bc 100644
--- a/spec/workers/group_import_worker_spec.rb
+++ b/spec/workers/group_import_worker_spec.rb
@@ -3,12 +3,14 @@
require 'spec_helper'
RSpec.describe GroupImportWorker do
- let!(:user) { create(:user) }
- let!(:group) { create(:group) }
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
subject { described_class.new }
before do
+ create(:group_import_state, group: group, user: user)
+
allow_next_instance_of(described_class) do |job|
allow(job).to receive(:jid).and_return(SecureRandom.hex(8))
end
@@ -26,44 +28,11 @@ RSpec.describe GroupImportWorker do
subject.perform(user.id, group.id)
end
- context 'when the import state does not exist' do
- it 'creates group import' do
- expect(group.import_state).to be_nil
-
- subject.perform(user.id, group.id)
- import_state = group.reload.import_state
-
- expect(import_state).to be_instance_of(GroupImportState)
- expect(import_state.status_name).to eq(:finished)
- expect(import_state.jid).not_to be_empty
- end
-
- it 'sets the group import status to started' do
- expect_next_instance_of(GroupImportState) do |import|
- expect(import).to receive(:start!).and_call_original
- end
-
- subject.perform(user.id, group.id)
- end
-
- it 'sets the group import status to finished' do
- expect_next_instance_of(GroupImportState) do |import|
- expect(import).to receive(:finish!).and_call_original
- end
+ it 'updates the existing state' do
+ expect { subject.perform(user.id, group.id) }
+ .not_to change { GroupImportState.count }
- subject.perform(user.id, group.id)
- end
- end
-
- context 'when the import state already exists' do
- it 'updates the existing state' do
- existing_state = create(:group_import_state, group: group)
-
- expect { subject.perform(user.id, group.id) }
- .not_to change { GroupImportState.count }
-
- expect(existing_state.reload).to be_finished
- end
+ expect(group.import_state.reload).to be_finished
end
end
@@ -83,11 +52,9 @@ RSpec.describe GroupImportWorker do
end
it 'sets the group import status to failed' do
- expect_next_instance_of(GroupImportState) do |import|
- expect(import).to receive(:fail_op).and_call_original
- end
-
expect { subject.perform(user.id, group.id) }.to raise_exception(Gitlab::ImportExport::Error)
+
+ expect(group.import_state.reload.status).to eq(-1)
end
end
end
diff --git a/spec/workers/incident_management/add_severity_system_note_worker_spec.rb b/spec/workers/incident_management/add_severity_system_note_worker_spec.rb
new file mode 100644
index 00000000000..203c62ffe6f
--- /dev/null
+++ b/spec/workers/incident_management/add_severity_system_note_worker_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IncidentManagement::AddSeveritySystemNoteWorker do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:incident) { create(:incident, project: project) }
+ let_it_be(:issuable_severity) { create(:issuable_severity, issue: incident, severity: :medium) }
+
+ describe '#perform' do
+ let(:incident_id) { incident.id }
+ let(:user_id) { user.id }
+
+ subject(:perform) { described_class.new.perform(incident_id, user_id) }
+
+ shared_examples 'does not add a system note' do
+ it 'does not change incident notes count' do
+ expect { perform }.not_to change { incident.notes.count }
+ end
+ end
+
+ context 'when incident and user exist' do
+ it 'creates a system note' do
+ expect { perform }.to change { incident.notes.where(author: user).count }.by(1)
+ end
+ end
+
+ context 'when incident does not exist' do
+ let(:incident_id) { -1 }
+
+ it_behaves_like 'does not add a system note'
+ end
+
+ context 'when incident_id is nil' do
+ let(:incident_id) { nil }
+
+ it_behaves_like 'does not add a system note'
+ end
+
+ context 'when issue is not an incident' do
+ let_it_be(:issue) { create(:issue, project: project) }
+ let(:incident_id) { issue.id }
+
+ it_behaves_like 'does not add a system note'
+ end
+
+ context 'when user does not exist' do
+ let(:user_id) { -1 }
+
+ it_behaves_like 'does not add a system note'
+ end
+
+ context 'when user_id is nil' do
+ let(:user_id) { nil }
+
+ it_behaves_like 'does not add a system note'
+ end
+ end
+end
diff --git a/spec/workers/incident_management/process_alert_worker_spec.rb b/spec/workers/incident_management/process_alert_worker_spec.rb
index 20ab283b49b..41d4f31da24 100644
--- a/spec/workers/incident_management/process_alert_worker_spec.rb
+++ b/spec/workers/incident_management/process_alert_worker_spec.rb
@@ -9,7 +9,6 @@ RSpec.describe IncidentManagement::ProcessAlertWorker do
describe '#perform' do
let_it_be(:started_at) { Time.now.rfc3339 }
let_it_be(:payload) { { 'title' => 'title', 'start_time' => started_at } }
- let_it_be(:parsed_payload) { Gitlab::Alerting::NotificationPayloadParser.call(payload, project) }
let_it_be(:alert) { create(:alert_management_alert, project: project, payload: payload, started_at: started_at) }
let(:created_issue) { Issue.last! }
@@ -68,7 +67,6 @@ RSpec.describe IncidentManagement::ProcessAlertWorker do
context 'prometheus alert' do
let_it_be(:alert) { create(:alert_management_alert, :prometheus, project: project, started_at: started_at) }
- let_it_be(:parsed_payload) { alert.payload }
it_behaves_like 'creates issue successfully'
end
diff --git a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
index c294892a66f..2ca4193aa72 100644
--- a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
+++ b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe IncidentManagement::ProcessPrometheusAlertWorker do
describe '#perform' do
let_it_be(:project) { create(:project) }
let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) }
- let(:payload_key) { Gitlab::Alerting::Alert.new(project: project, payload: alert_params).gitlab_fingerprint }
+ let(:payload_key) { Gitlab::AlertManagement::Payload::Prometheus.new(project: project, payload: alert_params).gitlab_fingerprint }
let!(:prometheus_alert_event) { create(:prometheus_alert_event, prometheus_alert: prometheus_alert, payload_key: payload_key) }
let!(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) }
diff --git a/spec/workers/member_invitation_reminder_emails_worker_spec.rb b/spec/workers/member_invitation_reminder_emails_worker_spec.rb
new file mode 100644
index 00000000000..64d096f84f5
--- /dev/null
+++ b/spec/workers/member_invitation_reminder_emails_worker_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MemberInvitationReminderEmailsWorker do
+ describe '#perform' do
+ subject { described_class.new.perform }
+
+ context 'feature flag disabled' do
+ before do
+ stub_experiment(invitation_reminders: false)
+ end
+
+ it 'does not raise an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ context 'feature flag enabled' do
+ before do
+ stub_experiment(invitation_reminders: true)
+ end
+
+ it 'does not raise an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb b/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
new file mode 100644
index 00000000000..19b79835825
--- /dev/null
+++ b/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Metrics::Dashboard::SyncDashboardsWorker do
+ include MetricsDashboardHelpers
+ subject(:worker) { described_class.new }
+
+ let(:project) { project_with_dashboard(dashboard_path) }
+ let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
+
+ describe ".perform" do
+ it 'imports metrics' do
+ expect { worker.perform(project.id) }.to change(PrometheusMetric, :count).by(3)
+ end
+
+ it 'is idempotent' do
+ 2.times do
+ worker.perform(project.id)
+ end
+
+ expect(PrometheusMetric.count).to eq(3)
+ end
+ end
+end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 50d164d1705..cb626b08456 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -290,7 +290,7 @@ RSpec.describe PostReceive do
# MySQL drops milliseconds in the timestamps, so advance at least
# a second to ensure we see changes.
- Timecop.freeze(1.second.from_now) do
+ travel_to(1.second.from_now) do
expect do
perform
project.reload
diff --git a/spec/workers/propagate_integration_group_worker_spec.rb b/spec/workers/propagate_integration_group_worker_spec.rb
new file mode 100644
index 00000000000..b3c9255db57
--- /dev/null
+++ b/spec/workers/propagate_integration_group_worker_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PropagateIntegrationGroupWorker do
+ describe '#perform' do
+ let_it_be(:group1) { create(:group) }
+ let_it_be(:group2) { create(:group) }
+ let_it_be(:integration) { create(:redmine_service, :instance) }
+
+ before do
+ allow(BulkCreateIntegrationService).to receive(:new)
+ .with(integration, match_array([group1, group2]), 'group')
+ .and_return(double(execute: nil))
+ end
+
+ it_behaves_like 'an idempotent worker' do
+ let(:job_args) { [integration.id, group1.id, group2.id] }
+
+ it 'calls to BulkCreateIntegrationService' do
+ expect(BulkCreateIntegrationService).to receive(:new)
+ .with(integration, match_array([group1, group2]), 'group')
+ .and_return(double(execute: nil))
+
+ subject
+ end
+ end
+
+ context 'with an invalid integration id' do
+ it 'returns without failure' do
+ expect(BulkCreateIntegrationService).not_to receive(:new)
+
+ subject.perform(0, group1.id, group2.id)
+ end
+ end
+ end
+end
diff --git a/spec/workers/propagate_integration_inherit_worker_spec.rb b/spec/workers/propagate_integration_inherit_worker_spec.rb
new file mode 100644
index 00000000000..88946b9926e
--- /dev/null
+++ b/spec/workers/propagate_integration_inherit_worker_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PropagateIntegrationInheritWorker do
+ describe '#perform' do
+ let_it_be(:integration) { create(:redmine_service, :instance) }
+ let_it_be(:integration1) { create(:redmine_service, inherit_from_id: integration.id) }
+ let_it_be(:integration2) { create(:bugzilla_service, inherit_from_id: integration.id) }
+ let_it_be(:integration3) { create(:redmine_service) }
+
+ before do
+ allow(BulkUpdateIntegrationService).to receive(:new)
+ .with(integration, match_array(integration1))
+ .and_return(double(execute: nil))
+ end
+
+ it_behaves_like 'an idempotent worker' do
+ let(:job_args) { [integration.id, integration1.id, integration3.id] }
+
+ it 'calls to BulkCreateIntegrationService' do
+ expect(BulkUpdateIntegrationService).to receive(:new)
+ .with(integration, match_array(integration1))
+ .and_return(double(execute: nil))
+
+ subject
+ end
+ end
+
+ context 'with an invalid integration id' do
+ it 'returns without failure' do
+ expect(BulkUpdateIntegrationService).not_to receive(:new)
+
+ subject.perform(0, integration1.id, integration3.id)
+ end
+ end
+ end
+end
diff --git a/spec/workers/propagate_integration_project_worker_spec.rb b/spec/workers/propagate_integration_project_worker_spec.rb
new file mode 100644
index 00000000000..3742ce5fde8
--- /dev/null
+++ b/spec/workers/propagate_integration_project_worker_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PropagateIntegrationProjectWorker do
+ describe '#perform' do
+ let_it_be(:project1) { create(:project) }
+ let_it_be(:project2) { create(:project) }
+ let_it_be(:integration) { create(:redmine_service, :instance) }
+
+ before do
+ allow(BulkCreateIntegrationService).to receive(:new)
+ .with(integration, match_array([project1, project2]), 'project')
+ .and_return(double(execute: nil))
+ end
+
+ it_behaves_like 'an idempotent worker' do
+ let(:job_args) { [integration.id, project1.id, project2.id] }
+
+ it 'calls to BulkCreateIntegrationService' do
+ expect(BulkCreateIntegrationService).to receive(:new)
+ .with(integration, match_array([project1, project2]), 'project')
+ .and_return(double(execute: nil))
+
+ subject
+ end
+ end
+
+ context 'with an invalid integration id' do
+ it 'returns without failure' do
+ expect(BulkCreateIntegrationService).not_to receive(:new)
+
+ subject.perform(0, project1.id, project2.id)
+ end
+ end
+ end
+end