summaryrefslogtreecommitdiff
path: root/spec/workers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/workers')
-rw-r--r--spec/workers/ci/build_finished_worker_spec.rb6
-rw-r--r--spec/workers/ci/initial_pipeline_process_worker_spec.rb58
-rw-r--r--spec/workers/cluster_provision_worker_spec.rb47
-rw-r--r--spec/workers/counters/cleanup_refresh_worker_spec.rb42
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/github_gists_import/finish_import_worker_spec.rb35
-rw-r--r--spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/github_gists_import/start_import_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/github_import/import_protected_branch_worker_spec.rb3
-rw-r--r--spec/workers/merge_requests/create_pipeline_worker_spec.rb6
-rw-r--r--spec/workers/pages/invalidate_domain_cache_worker_spec.rb66
-rw-r--r--spec/workers/personal_access_tokens/expired_notification_worker_spec.rb4
-rw-r--r--spec/workers/pipeline_schedule_worker_spec.rb29
-rw-r--r--spec/workers/projects/delete_branch_worker_spec.rb26
-rw-r--r--spec/workers/projects/finalize_project_statistics_refresh_worker_spec.rb41
-rw-r--r--spec/workers/projects/git_garbage_collect_worker_spec.rb5
-rw-r--r--spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb32
-rw-r--r--spec/workers/repository_import_worker_spec.rb104
-rw-r--r--spec/workers/run_pipeline_schedule_worker_spec.rb101
-rw-r--r--spec/workers/wait_for_cluster_creation_worker_spec.rb47
-rw-r--r--spec/workers/wikis/git_garbage_collect_worker_spec.rb2
21 files changed, 423 insertions, 236 deletions
diff --git a/spec/workers/ci/build_finished_worker_spec.rb b/spec/workers/ci/build_finished_worker_spec.rb
index e8bb3988001..049f3af1dd7 100644
--- a/spec/workers/ci/build_finished_worker_spec.rb
+++ b/spec/workers/ci/build_finished_worker_spec.rb
@@ -65,6 +65,12 @@ RSpec.describe Ci::BuildFinishedWorker do
subject
end
end
+
+ context 'when it has a token' do
+ it 'removes the token' do
+ expect { subject }.to change { build.reload.token }.to(nil)
+ end
+ end
end
context 'when build does not exist' do
diff --git a/spec/workers/ci/initial_pipeline_process_worker_spec.rb b/spec/workers/ci/initial_pipeline_process_worker_spec.rb
index 5fb8671fd5c..c7bbe83433e 100644
--- a/spec/workers/ci/initial_pipeline_process_worker_spec.rb
+++ b/spec/workers/ci/initial_pipeline_process_worker_spec.rb
@@ -2,12 +2,13 @@
require 'spec_helper'
-RSpec.describe Ci::InitialPipelineProcessWorker do
- describe '#perform' do
- let_it_be_with_reload(:pipeline) do
- create(:ci_pipeline, :with_job, status: :created)
- end
+RSpec.describe Ci::InitialPipelineProcessWorker, feature_category: :continuous_integration do
+ let_it_be(:project) { create(:project, :repository) }
+ let(:job) { build(:ci_build, project: project) }
+ let(:stage) { build(:ci_stage, project: project, statuses: [job]) }
+ let(:pipeline) { create(:ci_pipeline, stages: [stage], status: :created, project: project, builds: [job]) }
+ describe '#perform' do
include_examples 'an idempotent worker' do
let(:job_args) { pipeline.id }
@@ -19,5 +20,52 @@ RSpec.describe Ci::InitialPipelineProcessWorker do
expect(pipeline.reload).to be_pending
end
end
+
+ context 'when a pipeline does not contain a deployment job' do
+ it 'does not create any deployments' do
+ expect { subject }.not_to change { Deployment.count }
+ end
+ end
+
+ context 'when a pipeline contains a teardown job' do
+ let(:job) { build(:ci_build, :stop_review_app, project: project) }
+
+ before do
+ create(:environment, name: job.expanded_environment_name)
+ end
+
+ it 'does not create a deployment record' do
+ expect { subject }.not_to change { Deployment.count }
+
+ expect(job.deployment).to be_nil
+ end
+ end
+
+ context 'when a pipeline contains a deployment job' do
+ let(:job) { build(:ci_build, :start_review_app, project: project) }
+ let!(:environment) { create(:environment, project: project, name: job.expanded_environment_name) }
+
+ it 'creates a deployment record' do
+ expect { subject }.to change { Deployment.count }.by(1)
+
+ expect(job.deployment).to have_attributes(
+ project: job.project,
+ ref: job.ref,
+ sha: job.sha,
+ deployable: job,
+ deployable_type: 'CommitStatus',
+ environment: job.persisted_environment)
+ end
+
+ context 'when the corresponding environment does not exist' do
+ let(:environment) {}
+
+ it 'does not create a deployment record' do
+ expect { subject }.not_to change { Deployment.count }
+
+ expect(job.deployment).to be_nil
+ end
+ end
+ end
end
end
diff --git a/spec/workers/cluster_provision_worker_spec.rb b/spec/workers/cluster_provision_worker_spec.rb
deleted file mode 100644
index 2d6ca4ab7e3..00000000000
--- a/spec/workers/cluster_provision_worker_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ClusterProvisionWorker do
- describe '#perform' do
- context 'when provider type is gcp' do
- let(:cluster) { create(:cluster, provider_type: :gcp, provider_gcp: provider) }
- let(:provider) { create(:cluster_provider_gcp, :scheduled) }
-
- it 'provision a cluster' do
- expect_any_instance_of(Clusters::Gcp::ProvisionService).to receive(:execute).with(provider)
-
- described_class.new.perform(cluster.id)
- end
- end
-
- context 'when provider type is aws' do
- let(:cluster) { create(:cluster, provider_type: :aws, provider_aws: provider) }
- let(:provider) { create(:cluster_provider_aws, :scheduled) }
-
- it 'provision a cluster' do
- expect_any_instance_of(Clusters::Aws::ProvisionService).to receive(:execute).with(provider)
-
- described_class.new.perform(cluster.id)
- end
- end
-
- context 'when provider type is user' do
- let(:cluster) { create(:cluster, :provided_by_user) }
-
- it 'does not provision a cluster' do
- expect_any_instance_of(Clusters::Gcp::ProvisionService).not_to receive(:execute)
-
- described_class.new.perform(cluster.id)
- end
- end
-
- context 'when cluster does not exist' do
- it 'does not provision a cluster' do
- expect_any_instance_of(Clusters::Gcp::ProvisionService).not_to receive(:execute)
-
- described_class.new.perform(123)
- end
- end
- end
-end
diff --git a/spec/workers/counters/cleanup_refresh_worker_spec.rb b/spec/workers/counters/cleanup_refresh_worker_spec.rb
new file mode 100644
index 00000000000..a56c98f72a0
--- /dev/null
+++ b/spec/workers/counters/cleanup_refresh_worker_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Counters::CleanupRefreshWorker do
+ let(:model) { create(:project_statistics) }
+
+ describe '#perform', :redis do
+ let(:attribute) { :build_artifacts_size }
+ let(:worker) { described_class.new }
+
+ subject { worker.perform(model.class.name, model.id, attribute) }
+
+ it 'calls cleanup_refresh on the counter' do
+ expect_next_instance_of(Gitlab::Counters::BufferedCounter, model, attribute) do |counter|
+ expect(counter).to receive(:cleanup_refresh)
+ end
+
+ subject
+ end
+
+ context 'when model class does not exist' do
+ subject { worker.perform('NonExistentModel', 1, attribute) }
+
+ it 'does nothing' do
+ expect(Gitlab::Counters::BufferedCounter).not_to receive(:new)
+
+ subject
+ end
+ end
+
+ context 'when record does not exist' do
+ subject { worker.perform(model.class.name, non_existing_record_id, attribute) }
+
+ it 'does nothing' do
+ expect(Gitlab::Counters::BufferedCounter).not_to receive(:new)
+
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 788f5d8222c..c444e1f383c 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -210,6 +210,7 @@ RSpec.describe 'Every Sidekiq worker' do
'Deployments::LinkMergeRequestWorker' => 3,
'Deployments::SuccessWorker' => 3,
'Deployments::UpdateEnvironmentWorker' => 3,
+ 'Deployments::ApprovalWorker' => 3,
'DesignManagement::CopyDesignCollectionWorker' => 3,
'DesignManagement::NewVersionWorker' => 3,
'DestroyPagesDeploymentsWorker' => 3,
diff --git a/spec/workers/gitlab/github_gists_import/finish_import_worker_spec.rb b/spec/workers/gitlab/github_gists_import/finish_import_worker_spec.rb
index c4c19f2f9c5..cba6c578d11 100644
--- a/spec/workers/gitlab/github_gists_import/finish_import_worker_spec.rb
+++ b/spec/workers/gitlab/github_gists_import/finish_import_worker_spec.rb
@@ -2,13 +2,17 @@
require 'spec_helper'
-RSpec.describe Gitlab::GithubGistsImport::FinishImportWorker, feature_category: :importer do
+RSpec.describe Gitlab::GithubGistsImport::FinishImportWorker, :clean_gitlab_redis_cache, feature_category: :importers do
subject(:worker) { described_class.new }
let_it_be(:user) { create(:user) }
describe '#perform', :aggregate_failures do
context 'when there are no remaining jobs' do
+ before do
+ allow(Gitlab::Cache::Import::Caching).to receive(:values_from_hash).and_return(nil)
+ end
+
it 'marks import status as finished' do
waiter = instance_double(Gitlab::JobWaiter, key: :key, jobs_remaining: 0)
expect(Gitlab::JobWaiter).to receive(:new).and_return(waiter)
@@ -19,6 +23,8 @@ RSpec.describe Gitlab::GithubGistsImport::FinishImportWorker, feature_category:
expect(Gitlab::GithubImport::Logger)
.to receive(:info)
.with(user_id: user.id, message: 'GitHub Gists import finished')
+ expect(Notify).not_to receive(:github_gists_import_errors_email)
+ expect(Gitlab::Cache::Import::Caching).to receive(:expire).and_call_original
worker.perform(user.id, waiter.key, waiter.jobs_remaining)
end
@@ -35,6 +41,33 @@ RSpec.describe Gitlab::GithubGistsImport::FinishImportWorker, feature_category:
worker.perform(user.id, waiter.key, waiter.jobs_remaining)
end
end
+
+ context 'when some gists were failed to import' do
+ let(:errors) { { '12345' => 'Snippet maximum file count exceeded.' } }
+ let(:waiter) { instance_double(Gitlab::JobWaiter, key: :key, jobs_remaining: 0) }
+ let(:mail_instance) { instance_double(ActionMailer::MessageDelivery, deliver_now: true) }
+
+ before do
+ allow(Gitlab::Cache::Import::Caching).to receive(:values_from_hash).and_return(errors)
+ allow(Gitlab::JobWaiter).to receive(:new).and_return(waiter)
+ allow(waiter).to receive(:wait).with(described_class::BLOCKING_WAIT_TIME)
+ end
+
+ it 'sends an email to user' do
+ expect_next_instance_of(Gitlab::GithubGistsImport::Status) do |status|
+ expect(status).to receive(:finish!)
+ end
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:info)
+ .with(user_id: user.id, message: 'GitHub Gists import finished')
+ expect(Notify).to receive(:github_gists_import_errors_email)
+ .with(user.id, errors).once.and_return(mail_instance)
+ expect(mail_instance).to receive(:deliver_now)
+ expect(Gitlab::Cache::Import::Caching).to receive(:expire).and_call_original
+
+ worker.perform(user.id, waiter.key, waiter.jobs_remaining)
+ end
+ end
end
describe '.sidekiq_retries_exhausted' do
diff --git a/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
index dfc5084bb10..1c24cdcccae 100644
--- a/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
+++ b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::GithubGistsImport::ImportGistWorker, feature_category: :importer do
+RSpec.describe Gitlab::GithubGistsImport::ImportGistWorker, feature_category: :importers do
subject { described_class.new }
let_it_be(:user) { create(:user) }
diff --git a/spec/workers/gitlab/github_gists_import/start_import_worker_spec.rb b/spec/workers/gitlab/github_gists_import/start_import_worker_spec.rb
index 523b7463a9d..220f2bb0c75 100644
--- a/spec/workers/gitlab/github_gists_import/start_import_worker_spec.rb
+++ b/spec/workers/gitlab/github_gists_import/start_import_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::GithubGistsImport::StartImportWorker, feature_category: :importer do
+RSpec.describe Gitlab::GithubGistsImport::StartImportWorker, feature_category: :importers do
subject(:worker) { described_class.new }
let_it_be(:user) { create(:user) }
diff --git a/spec/workers/gitlab/github_import/import_protected_branch_worker_spec.rb b/spec/workers/gitlab/github_import/import_protected_branch_worker_spec.rb
index 4a3ef2bf560..c2b8ee661a3 100644
--- a/spec/workers/gitlab/github_import/import_protected_branch_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/import_protected_branch_worker_spec.rb
@@ -14,7 +14,8 @@ RSpec.describe Gitlab::GithubImport::ImportProtectedBranchWorker do
let(:json_hash) do
{
id: 'main',
- allow_force_pushes: true
+ allow_force_pushes: true,
+ allowed_to_push_users: []
}
end
diff --git a/spec/workers/merge_requests/create_pipeline_worker_spec.rb b/spec/workers/merge_requests/create_pipeline_worker_spec.rb
index 441d7652219..afb9fa1a549 100644
--- a/spec/workers/merge_requests/create_pipeline_worker_spec.rb
+++ b/spec/workers/merge_requests/create_pipeline_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::CreatePipelineWorker do
+RSpec.describe MergeRequests::CreatePipelineWorker, feature_category: :continuous_integration do
describe '#perform' do
let(:user) { create(:user) }
let(:project) { create(:project) }
@@ -17,7 +17,7 @@ RSpec.describe MergeRequests::CreatePipelineWorker do
expect_next_instance_of(MergeRequests::CreatePipelineService,
project: project,
current_user: user,
- params: { push_options: nil }) do |service|
+ params: { allow_duplicate: nil, push_options: nil }) do |service|
expect(service).to receive(:execute).with(merge_request)
end
@@ -38,7 +38,7 @@ RSpec.describe MergeRequests::CreatePipelineWorker do
expect_next_instance_of(MergeRequests::CreatePipelineService,
project: project,
current_user: user,
- params: { push_options: { ci: { skip: true } } }) do |service|
+ params: { allow_duplicate: nil, push_options: { ci: { skip: true } } }) do |service|
expect(service).to receive(:execute).with(merge_request)
end
diff --git a/spec/workers/pages/invalidate_domain_cache_worker_spec.rb b/spec/workers/pages/invalidate_domain_cache_worker_spec.rb
index c786d4658d4..b3c81b25a93 100644
--- a/spec/workers/pages/invalidate_domain_cache_worker_spec.rb
+++ b/spec/workers/pages/invalidate_domain_cache_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Pages::InvalidateDomainCacheWorker do
+RSpec.describe Pages::InvalidateDomainCacheWorker, feature_category: :pages do
shared_examples 'clears caches with' do |event_class:, event_data:, caches:|
include AfterNextHelpers
@@ -22,44 +22,70 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
end
end
+ context 'when a project have multiple domains' do
+ include AfterNextHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pages_domain) { create(:pages_domain, project: project) }
+ let_it_be(:pages_domain2) { create(:pages_domain, project: project) }
+
+ let(:event) do
+ Pages::PageDeployedEvent.new(
+ data: {
+ project_id: project.id,
+ namespace_id: project.namespace_id,
+ root_namespace_id: project.root_ancestor.id
+ }
+ )
+ end
+
+ subject { consume_event(subscriber: described_class, event: event) }
+
+ it 'clears the cache with Gitlab::Pages::CacheControl' do
+ expect_next(Gitlab::Pages::CacheControl, type: :namespace, id: project.namespace_id)
+ .to receive(:clear_cache)
+ expect_next(Gitlab::Pages::CacheControl, type: :domain, id: pages_domain.id)
+ .to receive(:clear_cache)
+ expect_next(Gitlab::Pages::CacheControl, type: :domain, id: pages_domain2.id)
+ .to receive(:clear_cache)
+
+ subject
+ end
+ end
+
it_behaves_like 'clears caches with',
event_class: Pages::PageDeployedEvent,
event_data: { project_id: 1, namespace_id: 2, root_namespace_id: 3 },
caches: [
- { type: :namespace, id: 3 },
- { type: :project, id: 1 }
+ { type: :namespace, id: 3 }
]
it_behaves_like 'clears caches with',
event_class: Pages::PageDeletedEvent,
event_data: { project_id: 1, namespace_id: 2, root_namespace_id: 3 },
caches: [
- { type: :namespace, id: 3 },
- { type: :project, id: 1 }
+ { type: :namespace, id: 3 }
]
it_behaves_like 'clears caches with',
event_class: Projects::ProjectDeletedEvent,
event_data: { project_id: 1, namespace_id: 2, root_namespace_id: 3 },
caches: [
- { type: :namespace, id: 3 },
- { type: :project, id: 1 }
+ { type: :namespace, id: 3 }
]
it_behaves_like 'clears caches with',
event_class: Projects::ProjectCreatedEvent,
event_data: { project_id: 1, namespace_id: 2, root_namespace_id: 3 },
caches: [
- { type: :namespace, id: 3 },
- { type: :project, id: 1 }
+ { type: :namespace, id: 3 }
]
it_behaves_like 'clears caches with',
event_class: Projects::ProjectArchivedEvent,
event_data: { project_id: 1, namespace_id: 2, root_namespace_id: 3 },
caches: [
- { type: :namespace, id: 3 },
- { type: :project, id: 1 }
+ { type: :namespace, id: 3 }
]
it_behaves_like 'clears caches with',
@@ -72,8 +98,7 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
new_path: 'new_path'
},
caches: [
- { type: :namespace, id: 3 },
- { type: :project, id: 1 }
+ { type: :namespace, id: 3 }
]
it_behaves_like 'clears caches with',
@@ -86,7 +111,6 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
new_root_namespace_id: 5
},
caches: [
- { type: :project, id: 1 },
{ type: :namespace, id: 3 },
{ type: :namespace, id: 5 }
]
@@ -131,10 +155,11 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
project_id: 1,
namespace_id: 2,
root_namespace_id: 3,
+ domain_id: 4,
domain: 'somedomain.com'
},
caches: [
- { type: :project, id: 1 },
+ { type: :domain, id: 4 },
{ type: :namespace, id: 3 }
]
@@ -144,10 +169,11 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
project_id: 1,
namespace_id: 2,
root_namespace_id: 3,
+ domain_id: 4,
domain: 'somedomain.com'
},
caches: [
- { type: :project, id: 1 },
+ { type: :domain, id: 4 },
{ type: :namespace, id: 3 }
]
@@ -157,10 +183,11 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
project_id: 1,
namespace_id: 2,
root_namespace_id: 3,
+ domain_id: 4,
domain: 'somedomain.com'
},
caches: [
- { type: :project, id: 1 },
+ { type: :domain, id: 4 },
{ type: :namespace, id: 3 }
]
@@ -172,10 +199,11 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
project_id: 1,
namespace_id: 2,
root_namespace_id: 3,
+ domain_id: 4,
attributes: [attribute]
},
caches: [
- { type: :project, id: 1 },
+ { type: :domain, id: 4 },
{ type: :namespace, id: 3 }
]
end
@@ -204,7 +232,6 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
features: ['pages_access_level']
},
caches: [
- { type: :project, id: 1 },
{ type: :namespace, id: 3 }
]
@@ -234,7 +261,6 @@ RSpec.describe Pages::InvalidateDomainCacheWorker do
new_root_namespace_id: 5
},
caches: [
- { type: :project, id: 1 },
{ type: :namespace, id: 5 }
]
end
diff --git a/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb b/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb
index 3ff67f47523..7c3c48b3f80 100644
--- a/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb
+++ b/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe PersonalAccessTokens::ExpiredNotificationWorker, type: :worker do
it 'uses notification service to send email to the user' do
expect_next_instance_of(NotificationService) do |notification_service|
- expect(notification_service).to receive(:access_token_expired).with(expired_today.user)
+ expect(notification_service).to receive(:access_token_expired).with(expired_today.user, [expired_today.name])
end
worker.perform
@@ -25,7 +25,7 @@ RSpec.describe PersonalAccessTokens::ExpiredNotificationWorker, type: :worker do
shared_examples 'expiry notification is not required to be sent for the token' do
it do
expect_next_instance_of(NotificationService) do |notification_service|
- expect(notification_service).not_to receive(:access_token_expired).with(token.user)
+ expect(notification_service).not_to receive(:access_token_expired).with(token.user, [token.name])
end
worker.perform
diff --git a/spec/workers/pipeline_schedule_worker_spec.rb b/spec/workers/pipeline_schedule_worker_spec.rb
index d23907a8def..db58dc00338 100644
--- a/spec/workers/pipeline_schedule_worker_spec.rb
+++ b/spec/workers/pipeline_schedule_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe PipelineScheduleWorker do
+RSpec.describe PipelineScheduleWorker, :sidekiq_inline, feature_category: :continuous_integration do
include ExclusiveLeaseHelpers
subject { described_class.new.perform }
@@ -30,7 +30,7 @@ RSpec.describe PipelineScheduleWorker do
project.add_maintainer(user)
end
- context 'when there is a scheduled pipeline within next_run_at', :sidekiq_inline do
+ context 'when there is a scheduled pipeline within next_run_at' do
shared_examples 'successful scheduling' do
it 'creates a new pipeline' do
expect { subject }.to change { project.ci_pipelines.count }.by(1)
@@ -49,7 +49,19 @@ RSpec.describe PipelineScheduleWorker do
end
end
- it_behaves_like 'successful scheduling'
+ shared_examples 'successful scheduling with/without ci_use_run_pipeline_schedule_worker' do
+ it_behaves_like 'successful scheduling'
+
+ context 'when feature flag ci_use_run_pipeline_schedule_worker is disabled' do
+ before do
+ stub_feature_flags(ci_use_run_pipeline_schedule_worker: false)
+ end
+
+ it_behaves_like 'successful scheduling'
+ end
+ end
+
+ it_behaves_like 'successful scheduling with/without ci_use_run_pipeline_schedule_worker'
context 'when the latest commit contains [ci skip]' do
before do
@@ -58,7 +70,7 @@ RSpec.describe PipelineScheduleWorker do
.and_return('some commit [ci skip]')
end
- it_behaves_like 'successful scheduling'
+ it_behaves_like 'successful scheduling with/without ci_use_run_pipeline_schedule_worker'
end
end
@@ -123,4 +135,13 @@ RSpec.describe PipelineScheduleWorker do
expect { subject }.not_to raise_error
end
end
+
+ context 'when max retry attempts reach' do
+ let!(:lease) { stub_exclusive_lease_taken(described_class.name.underscore) }
+
+ it 'does not raise error' do
+ expect(lease).to receive(:try_obtain).exactly(described_class::LOCK_RETRY + 1).times
+ expect { subject }.to raise_error(Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError)
+ end
+ end
end
diff --git a/spec/workers/projects/delete_branch_worker_spec.rb b/spec/workers/projects/delete_branch_worker_spec.rb
index c1289f56929..771ab3def84 100644
--- a/spec/workers/projects/delete_branch_worker_spec.rb
+++ b/spec/workers/projects/delete_branch_worker_spec.rb
@@ -64,9 +64,11 @@ RSpec.describe Projects::DeleteBranchWorker, feature_category: :source_code_mana
expect(instance).to receive(:execute).with(branch).and_return(service_result)
end
- expect(service_result).to receive(:track_and_raise_exception).and_call_original
+ expect(service_result).to receive(:log_and_raise_exception).and_call_original
- expect { worker.perform(project.id, user.id, branch) }.to raise_error(StandardError)
+ expect do
+ worker.perform(project.id, user.id, branch)
+ end.to raise_error(Projects::DeleteBranchWorker::GitReferenceLockedError)
end
end
@@ -78,25 +80,7 @@ RSpec.describe Projects::DeleteBranchWorker, feature_category: :source_code_mana
expect(instance).to receive(:execute).with(branch).and_return(service_result)
end
- expect(service_result).not_to receive(:track_and_raise_exception)
-
- expect { worker.perform(project.id, user.id, branch) }.not_to raise_error
- end
- end
-
- context 'when track_and_raise_delete_source_errors is disabled' do
- let(:status_code) { 400 }
-
- before do
- stub_feature_flags(track_and_raise_delete_source_errors: false)
- end
-
- it 'does not track the exception' do
- expect_next_instance_of(::Branches::DeleteService) do |instance|
- expect(instance).to receive(:execute).with(branch).and_return(service_result)
- end
-
- expect(service_result).not_to receive(:track_and_raise_exception)
+ expect(service_result).not_to receive(:log_and_raise_exception)
expect { worker.perform(project.id, user.id, branch) }.not_to raise_error
end
diff --git a/spec/workers/projects/finalize_project_statistics_refresh_worker_spec.rb b/spec/workers/projects/finalize_project_statistics_refresh_worker_spec.rb
new file mode 100644
index 00000000000..932ba29f806
--- /dev/null
+++ b/spec/workers/projects/finalize_project_statistics_refresh_worker_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::FinalizeProjectStatisticsRefreshWorker do
+ let_it_be(:record) { create(:project_build_artifacts_size_refresh, :finalizing) }
+
+ describe '#perform' do
+ let(:attribute) { record.class.counter_attributes.first }
+ let(:worker) { described_class.new }
+
+ subject { worker.perform(record.class.name, record.id) }
+
+ it 'stores the refresh increment to the buffered counter' do
+ expect(record.class).to receive(:find_by_id).and_return(record)
+ expect(record).to receive(:finalize!)
+
+ subject
+ end
+
+ context 'when record class does not exist' do
+ subject { worker.perform('NonExistentModel', 1) }
+
+ it 'does nothing' do
+ expect(record).not_to receive(:finalize!)
+
+ subject
+ end
+ end
+
+ context 'when record does not exist' do
+ subject { worker.perform(record.class.name, non_existing_record_id) }
+
+ it 'does nothing' do
+ expect(record).not_to receive(:finalize!)
+
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/workers/projects/git_garbage_collect_worker_spec.rb b/spec/workers/projects/git_garbage_collect_worker_spec.rb
index ae567107443..899e3ed2007 100644
--- a/spec/workers/projects/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/projects/git_garbage_collect_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::GitGarbageCollectWorker do
+RSpec.describe Projects::GitGarbageCollectWorker, feature_category: :source_code_management do
let_it_be(:project) { create(:project, :repository) }
it_behaves_like 'can collect git garbage' do
@@ -24,8 +24,7 @@ RSpec.describe Projects::GitGarbageCollectWorker do
end
context 'when the repository has joined a pool' do
- let!(:pool) { create(:pool_repository, :ready) }
- let(:project) { pool.source_project }
+ let_it_be(:pool) { create(:pool_repository, :ready, source_project: project) }
it 'ensures the repositories are linked' do
expect(project.pool_repository).to receive(:link_repository).once
diff --git a/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb b/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb
index c7e45e7e4d7..00c45255316 100644
--- a/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb
+++ b/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb
@@ -62,14 +62,38 @@ RSpec.describe Projects::RefreshBuildArtifactsSizeStatisticsWorker do
describe '#max_running_jobs' do
subject { worker.max_running_jobs }
- it { is_expected.to eq(10) }
+ before do
+ stub_feature_flags(
+ projects_build_artifacts_size_refresh: false,
+ projects_build_artifacts_size_refresh_medium: false,
+ projects_build_artifacts_size_refresh_high: false
+ )
+ end
- context 'when projects_build_artifacts_size_refresh flag is disabled' do
+ it { is_expected.to eq(0) }
+
+ context 'when projects_build_artifacts_size_refresh flag is enabled' do
before do
- stub_feature_flags(projects_build_artifacts_size_refresh: false)
+ stub_feature_flags(projects_build_artifacts_size_refresh: true)
end
- it { is_expected.to eq(0) }
+ it { is_expected.to eq(described_class::MAX_RUNNING_LOW) }
+ end
+
+ context 'when projects_build_artifacts_size_refresh_medium flag is enabled' do
+ before do
+ stub_feature_flags(projects_build_artifacts_size_refresh_medium: true)
+ end
+
+ it { is_expected.to eq(described_class::MAX_RUNNING_MEDIUM) }
+ end
+
+ context 'when projects_build_artifacts_size_refresh_high flag is enabled' do
+ before do
+ stub_feature_flags(projects_build_artifacts_size_refresh_high: true)
+ end
+
+ it { is_expected.to eq(described_class::MAX_RUNNING_HIGH) }
end
end
end
diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb
index 1dc77fbf83f..ca7c13fe24e 100644
--- a/spec/workers/repository_import_worker_spec.rb
+++ b/spec/workers/repository_import_worker_spec.rb
@@ -2,92 +2,88 @@
require 'spec_helper'
-RSpec.describe RepositoryImportWorker do
+RSpec.describe RepositoryImportWorker, feature_category: :importers do
describe '#perform' do
- let(:project) { create(:project, :import_scheduled) }
- let(:import_state) { project.import_state }
-
- context 'when worker was reset without cleanup' do
- it 'imports the project successfully' do
- jid = '12345678'
- started_project = create(:project)
- started_import_state = create(:import_state, :started, project: started_project, jid: jid)
-
- allow(subject).to receive(:jid).and_return(jid)
+ let(:project) { build_stubbed(:project, :import_scheduled, import_state: import_state, import_url: 'url') }
+ let(:import_state) { create(:import_state, status: :scheduled) }
+ let(:jid) { '12345678' }
+
+ before do
+ allow(subject).to receive(:jid).and_return(jid)
+ allow(Project).to receive(:find_by_id).with(project.id).and_return(project)
+ allow(project).to receive(:after_import)
+ allow(import_state).to receive(:start).and_return(true)
+ end
- expect_next_instance_of(Projects::ImportService) do |instance|
- expect(instance).to receive(:execute).and_return({ status: :ok })
- end
+ context 'when project not found (deleted)' do
+ before do
+ allow(Project).to receive(:find_by_id).with(project.id).and_return(nil)
+ end
- # Works around https://github.com/rspec/rspec-mocks/issues/910
- expect(Project).to receive(:find).with(started_project.id).and_return(started_project)
- expect(started_project.repository).to receive(:expire_emptiness_caches)
- expect(started_project.wiki.repository).to receive(:expire_emptiness_caches)
- expect(started_import_state).to receive(:finish)
+ it 'does not raise any exception' do
+ expect(Projects::ImportService).not_to receive(:new)
- subject.perform(started_project.id)
+ expect { subject.perform(project.id) }.not_to raise_error
end
end
- context 'when the import was successful' do
- it 'imports a project' do
+ context 'when import_state is scheduled' do
+ it 'imports the project successfully' do
expect_next_instance_of(Projects::ImportService) do |instance|
expect(instance).to receive(:execute).and_return({ status: :ok })
end
- # Works around https://github.com/rspec/rspec-mocks/issues/910
- expect(Project).to receive(:find).with(project.id).and_return(project)
- expect(project.repository).to receive(:expire_emptiness_caches)
- expect(project.wiki.repository).to receive(:expire_emptiness_caches)
- expect(import_state).to receive(:finish)
-
subject.perform(project.id)
+
+ expect(project).to have_received(:after_import)
+ expect(import_state).to have_received(:start)
end
end
- context 'when the import has failed' do
- it 'updates the error on Import/Export & hides credentials from import URL' do
- import_url = 'https://user:pass@test.com/root/repoC.git/'
- error = "#{import_url} not found"
-
- import_state.update!(jid: '123')
- project.update!(import_type: 'gitlab_project')
+ context 'when worker was reset without cleanup (import_state is started)' do
+ let(:import_state) { create(:import_state, :started, jid: jid) }
+ it 'imports the project successfully' do
expect_next_instance_of(Projects::ImportService) do |instance|
- expect(instance).to receive(:track_start_import).and_raise(StandardError, error)
+ expect(instance).to receive(:execute).and_return({ status: :ok })
end
- expect { subject.perform(project.id) }.not_to raise_error
+ subject.perform(project.id)
- import_state.reload
- expect(import_state.jid).to eq('123')
- expect(import_state.status).to eq('failed')
- expect(import_state.last_error).to include("[FILTERED] not found")
- expect(import_state.last_error).not_to include(import_url)
+ expect(project).to have_received(:after_import)
+ expect(import_state).not_to have_received(:start)
end
end
context 'when using an asynchronous importer' do
it 'does not mark the import process as finished' do
- service = double(:service)
+ expect_next_instance_of(Projects::ImportService) do |instance|
+ expect(instance).to receive(:execute).and_return({ status: :ok })
+ expect(instance).to receive(:async?).and_return(true)
+ end
+
+ subject.perform(project.id)
- allow(Projects::ImportService)
- .to receive(:new)
- .and_return(service)
+ expect(project).not_to have_received(:after_import)
+ end
+ end
- allow(service)
- .to receive(:execute)
- .and_return(true)
+ context 'when the import has failed' do
+ let(:error) { "https://user:pass@test.com/root/repoC.git/ not found" }
- allow(service)
- .to receive(:async?)
- .and_return(true)
+ before do
+ allow(import_state).to receive(:mark_as_failed)
+ end
- expect_next_instance_of(ProjectImportState) do |instance|
- expect(instance).not_to receive(:finish)
+ it 'marks import_state as failed' do
+ expect_next_instance_of(Projects::ImportService) do |instance|
+ expect(instance).to receive(:execute).and_return({ status: :error, message: error })
end
subject.perform(project.id)
+
+ expect(import_state).to have_received(:mark_as_failed).with(error)
+ expect(project).not_to have_received(:after_import)
end
end
end
diff --git a/spec/workers/run_pipeline_schedule_worker_spec.rb b/spec/workers/run_pipeline_schedule_worker_spec.rb
index 4fdf6149435..25158de3341 100644
--- a/spec/workers/run_pipeline_schedule_worker_spec.rb
+++ b/spec/workers/run_pipeline_schedule_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe RunPipelineScheduleWorker do
+RSpec.describe RunPipelineScheduleWorker, feature_category: :continuous_integration do
it 'has an until_executed deduplicate strategy' do
expect(described_class.get_deduplicate_strategy).to eq(:until_executed)
end
@@ -21,6 +21,11 @@ RSpec.describe RunPipelineScheduleWorker do
end
end
+ it 'accepts an option' do
+ expect { worker.perform(pipeline_schedule.id, user.id, {}) }.not_to raise_error
+ expect { worker.perform(pipeline_schedule.id, user.id, {}, {}) }.to raise_error(ArgumentError)
+ end
+
context 'when a schedule not found' do
it 'does not call the Service' do
expect(Ci::CreatePipelineService).not_to receive(:new)
@@ -56,37 +61,91 @@ RSpec.describe RunPipelineScheduleWorker do
let(:create_pipeline_service) { instance_double(Ci::CreatePipelineService, execute: service_response) }
let(:service_response) { instance_double(ServiceResponse, payload: pipeline, error?: false) }
- before do
- expect(Ci::CreatePipelineService).to receive(:new).with(project, user, ref: pipeline_schedule.ref).and_return(create_pipeline_service)
+ context 'when pipeline can be created' do
+ before do
+ expect(Ci::CreatePipelineService).to receive(:new).with(project, user, ref: pipeline_schedule.ref).and_return(create_pipeline_service)
- expect(create_pipeline_service).to receive(:execute).with(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: pipeline_schedule).and_return(service_response)
- end
+ expect(create_pipeline_service).to receive(:execute).with(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: pipeline_schedule).and_return(service_response)
+ end
+
+ context "when pipeline is persisted" do
+ let(:pipeline) { instance_double(Ci::Pipeline, persisted?: true) }
- context "when pipeline is persisted" do
- let(:pipeline) { instance_double(Ci::Pipeline, persisted?: true) }
+ it "returns the service response" do
+ expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response)
+ end
- it "returns the service response" do
- expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response)
+ it "does not log errors" do
+ expect(worker).not_to receive(:log_extra_metadata_on_done)
+
+ expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response)
+ end
+
+ it "changes the next_run_at" do
+ expect { worker.perform(pipeline_schedule.id, user.id) }.to change { pipeline_schedule.reload.next_run_at }.by(1.day)
+ end
+
+ context 'when feature flag ci_use_run_pipeline_schedule_worker is disabled' do
+ before do
+ stub_feature_flags(ci_use_run_pipeline_schedule_worker: false)
+ end
+
+ it 'does not change the next_run_at' do
+ expect { worker.perform(pipeline_schedule.id, user.id) }.not_to change { pipeline_schedule.reload.next_run_at }
+ end
+ end
end
- it "does not log errors" do
- expect(worker).not_to receive(:log_extra_metadata_on_done)
+ context "when pipeline was not persisted" do
+ let(:service_response) { instance_double(ServiceResponse, error?: true, message: "Error", payload: pipeline) }
+ let(:pipeline) { instance_double(Ci::Pipeline, persisted?: false) }
+
+ it "logs a pipeline creation error" do
+ expect(worker)
+ .to receive(:log_extra_metadata_on_done)
+ .with(:pipeline_creation_error, service_response.message)
+ .and_call_original
- expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response)
+ expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response.message)
+ end
end
end
- context "when pipeline was not persisted" do
- let(:service_response) { instance_double(ServiceResponse, error?: true, message: "Error", payload: pipeline) }
- let(:pipeline) { instance_double(Ci::Pipeline, persisted?: false) }
+ context 'when schedule is already executed' do
+ let(:time_in_future) { 1.hour.since }
+
+ before do
+ pipeline_schedule.update_column(:next_run_at, time_in_future)
+ end
+
+ it 'does not change the next_run_at' do
+ expect { worker.perform(pipeline_schedule.id, user.id) }.to not_change { pipeline_schedule.reload.next_run_at }
+ end
+
+ it 'does not create a pipeline' do
+ expect(Ci::CreatePipelineService).not_to receive(:new)
+
+ worker.perform(pipeline_schedule.id, user.id)
+ end
+
+ context 'when feature flag ci_use_run_pipeline_schedule_worker is disabled' do
+ let(:pipeline) { instance_double(Ci::Pipeline, persisted?: true) }
+
+ before do
+ stub_feature_flags(ci_use_run_pipeline_schedule_worker: false)
+
+ expect(Ci::CreatePipelineService).to receive(:new).with(project, user, ref: pipeline_schedule.ref).and_return(create_pipeline_service)
+
+ expect(create_pipeline_service).to receive(:execute).with(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: pipeline_schedule).and_return(service_response)
+ end
- it "logs a pipeline creation error" do
- expect(worker)
- .to receive(:log_extra_metadata_on_done)
- .with(:pipeline_creation_error, service_response.message)
- .and_call_original
+ it 'does not change the next_run_at' do
+ expect { worker.perform(pipeline_schedule.id, user.id) }.to not_change { pipeline_schedule.reload.next_run_at }
+ end
- expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response.message)
+ it "returns the service response" do
+ expect(worker.perform(pipeline_schedule.id, user.id)).to eq(service_response)
+ end
end
end
end
diff --git a/spec/workers/wait_for_cluster_creation_worker_spec.rb b/spec/workers/wait_for_cluster_creation_worker_spec.rb
deleted file mode 100644
index 9079dff1afe..00000000000
--- a/spec/workers/wait_for_cluster_creation_worker_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe WaitForClusterCreationWorker do
- describe '#perform' do
- context 'when provider type is gcp' do
- let(:cluster) { create(:cluster, provider_type: :gcp, provider_gcp: provider) }
- let(:provider) { create(:cluster_provider_gcp, :creating) }
-
- it 'provisions a cluster' do
- expect_any_instance_of(Clusters::Gcp::VerifyProvisionStatusService).to receive(:execute).with(provider)
-
- described_class.new.perform(cluster.id)
- end
- end
-
- context 'when provider type is aws' do
- let(:cluster) { create(:cluster, provider_type: :aws, provider_aws: provider) }
- let(:provider) { create(:cluster_provider_aws, :creating) }
-
- it 'provisions a cluster' do
- expect_any_instance_of(Clusters::Aws::VerifyProvisionStatusService).to receive(:execute).with(provider)
-
- described_class.new.perform(cluster.id)
- end
- end
-
- context 'when provider type is user' do
- let(:cluster) { create(:cluster, provider_type: :user) }
-
- it 'does not provision a cluster' do
- expect_any_instance_of(Clusters::Gcp::VerifyProvisionStatusService).not_to receive(:execute)
-
- described_class.new.perform(cluster.id)
- end
- end
-
- context 'when cluster does not exist' do
- it 'does not provision a cluster' do
- expect_any_instance_of(Clusters::Gcp::VerifyProvisionStatusService).not_to receive(:execute)
-
- described_class.new.perform(123)
- end
- end
- end
-end
diff --git a/spec/workers/wikis/git_garbage_collect_worker_spec.rb b/spec/workers/wikis/git_garbage_collect_worker_spec.rb
index 77c2e49a83a..2c6899848cf 100644
--- a/spec/workers/wikis/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/wikis/git_garbage_collect_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Wikis::GitGarbageCollectWorker do
+RSpec.describe Wikis::GitGarbageCollectWorker, feature_category: :source_code_management do
it_behaves_like 'can collect git garbage' do
let_it_be(:resource) { create(:project_wiki) }
let_it_be(:page) { create(:wiki_page, wiki: resource) }