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:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-04 15:19:41 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-04 15:19:41 +0300
commitac72b79188a14a28eafe55d32641f9939cf5d9c4 (patch)
treed6f6f349fb30017a600ebdee07b832889615978e /spec/services
parent8f89276d8498f45459bca67493eccd1bdf055330 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/services')
-rw-r--r--spec/services/ci/cancel_pipeline_service_spec.rb76
-rw-r--r--spec/services/ci/create_pipeline_service/workflow_auto_cancel_spec.rb2
-rw-r--r--spec/services/ci/pipeline_creation/cancel_redundant_pipelines_service_spec.rb209
-rw-r--r--spec/services/members/create_service_spec.rb26
4 files changed, 297 insertions, 16 deletions
diff --git a/spec/services/ci/cancel_pipeline_service_spec.rb b/spec/services/ci/cancel_pipeline_service_spec.rb
index 256d2db1ed2..6051485c4df 100644
--- a/spec/services/ci/cancel_pipeline_service_spec.rb
+++ b/spec/services/ci/cancel_pipeline_service_spec.rb
@@ -13,12 +13,14 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
current_user: current_user,
cascade_to_children: cascade_to_children,
auto_canceled_by_pipeline: auto_canceled_by_pipeline,
- execute_async: execute_async)
+ execute_async: execute_async,
+ safe_cancellation: safe_cancellation)
end
let(:cascade_to_children) { true }
let(:auto_canceled_by_pipeline) { nil }
let(:execute_async) { true }
+ let(:safe_cancellation) { false }
shared_examples 'force_execute' do
context 'when pipeline is not cancelable' do
@@ -30,9 +32,14 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
context 'when pipeline is cancelable' do
before do
- create(:ci_build, :running, pipeline: pipeline)
- create(:ci_build, :created, pipeline: pipeline)
- create(:ci_build, :success, pipeline: pipeline)
+ create(:ci_build, :running, pipeline: pipeline, name: 'build1')
+ create(:ci_build, :created, pipeline: pipeline, name: 'build2')
+ create(:ci_build, :success, pipeline: pipeline, name: 'build3')
+ create(:ci_build, :pending, :interruptible, pipeline: pipeline, name: 'build4')
+
+ create(:ci_bridge, :running, pipeline: pipeline, name: 'bridge1')
+ create(:ci_bridge, :running, :interruptible, pipeline: pipeline, name: 'bridge2')
+ create(:ci_bridge, :success, :interruptible, pipeline: pipeline, name: 'bridge3')
end
it 'logs the event' do
@@ -55,7 +62,15 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
it 'cancels all cancelable jobs' do
expect(response).to be_success
- expect(pipeline.all_jobs.pluck(:status)).to match_array(%w[canceled canceled success])
+ expect(pipeline.all_jobs.pluck(:name, :status)).to match_array([
+ %w[build1 canceled],
+ %w[build2 canceled],
+ %w[build3 success],
+ %w[build4 canceled],
+ %w[bridge1 canceled],
+ %w[bridge2 canceled],
+ %w[bridge3 success]
+ ])
end
context 'when auto_canceled_by_pipeline is provided' do
@@ -74,6 +89,28 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
end
end
+ context 'when cascade_to_children: false and safe_cancellation: true' do
+ # We are testing the `safe_cancellation: true`` case with only `cascade_to_children: false`
+ # because `safe_cancellation` is passed as `true` only when `cascade_to_children` is `false`
+ # from `CancelRedundantPipelinesService`.
+
+ let(:cascade_to_children) { false }
+ let(:safe_cancellation) { true }
+
+ it 'cancels only interruptible jobs' do
+ expect(response).to be_success
+ expect(pipeline.all_jobs.pluck(:name, :status)).to match_array([
+ %w[build1 running],
+ %w[build2 created],
+ %w[build3 success],
+ %w[build4 canceled],
+ %w[bridge1 running],
+ %w[bridge2 canceled],
+ %w[bridge3 success]
+ ])
+ end
+ end
+
context 'when pipeline has child pipelines' do
let(:child_pipeline) { create(:ci_pipeline, child_of: pipeline) }
let!(:child_job) { create(:ci_build, :running, pipeline: child_pipeline) }
@@ -81,8 +118,8 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
let!(:grandchild_job) { create(:ci_build, :running, pipeline: grandchild_pipeline) }
before do
- child_pipeline.source_bridge.update!(status: :running)
- grandchild_pipeline.source_bridge.update!(status: :running)
+ child_pipeline.source_bridge.update!(name: 'child_pipeline_bridge', status: :running)
+ grandchild_pipeline.source_bridge.update!(name: 'grandchild_pipeline_bridge', status: :running)
end
context 'when execute_async: false' do
@@ -91,8 +128,15 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
it 'cancels the bridge jobs and child jobs' do
expect(response).to be_success
- expect(pipeline.bridges.pluck(:status)).to be_all('canceled')
- expect(child_pipeline.bridges.pluck(:status)).to be_all('canceled')
+ expect(pipeline.bridges.pluck(:name, :status)).to match_array([
+ %w[bridge1 canceled],
+ %w[bridge2 canceled],
+ %w[bridge3 success],
+ %w[child_pipeline_bridge canceled]
+ ])
+ expect(child_pipeline.bridges.pluck(:name, :status)).to match_array([
+ %w[grandchild_pipeline_bridge canceled]
+ ])
expect(child_job.reload).to be_canceled
expect(grandchild_job.reload).to be_canceled
end
@@ -110,7 +154,12 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
expect(response).to be_success
- expect(pipeline.bridges.pluck(:status)).to be_all('canceled')
+ expect(pipeline.bridges.pluck(:name, :status)).to match_array([
+ %w[bridge1 canceled],
+ %w[bridge2 canceled],
+ %w[bridge3 success],
+ %w[child_pipeline_bridge canceled]
+ ])
end
end
@@ -124,7 +173,12 @@ RSpec.describe Ci::CancelPipelineService, :aggregate_failures, feature_category:
expect(response).to be_success
- expect(pipeline.bridges.pluck(:status)).to be_all('canceled')
+ expect(pipeline.bridges.pluck(:name, :status)).to match_array([
+ %w[bridge1 canceled],
+ %w[bridge2 canceled],
+ %w[bridge3 success],
+ %w[child_pipeline_bridge canceled]
+ ])
expect(child_job.reload).to be_running
end
end
diff --git a/spec/services/ci/create_pipeline_service/workflow_auto_cancel_spec.rb b/spec/services/ci/create_pipeline_service/workflow_auto_cancel_spec.rb
index 851c6f8fbea..3ad6164bd01 100644
--- a/spec/services/ci/create_pipeline_service/workflow_auto_cancel_spec.rb
+++ b/spec/services/ci/create_pipeline_service/workflow_auto_cancel_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
it 'creates a pipeline with errors' do
expect(pipeline).to be_persisted
expect(pipeline.errors.full_messages).to include(
- 'workflow:auto_cancel on new commit must be one of: conservative, interruptible, disabled')
+ 'workflow:auto_cancel on new commit must be one of: conservative, interruptible, none')
end
end
end
diff --git a/spec/services/ci/pipeline_creation/cancel_redundant_pipelines_service_spec.rb b/spec/services/ci/pipeline_creation/cancel_redundant_pipelines_service_spec.rb
index 0d83187f9e4..7b5eef92f53 100644
--- a/spec/services/ci/pipeline_creation/cancel_redundant_pipelines_service_spec.rb
+++ b/spec/services/ci/pipeline_creation/cancel_redundant_pipelines_service_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe Ci::PipelineCreation::CancelRedundantPipelinesService, feature_ca
project.update!(auto_cancel_pending_pipelines: 'enabled')
end
- it 'cancels only previous interruptible builds' do
+ it 'cancels only previous non started builds' do
execute
expect(build_statuses(prev_pipeline)).to contain_exactly('canceled', 'success', 'canceled')
@@ -153,6 +153,36 @@ RSpec.describe Ci::PipelineCreation::CancelRedundantPipelinesService, feature_ca
expect(build_statuses(child_pipeline)).to contain_exactly('running', 'success')
end
+
+ context 'when the child pipeline auto_cancel_on_new_commit is `interruptible`' do
+ before do
+ child_pipeline.create_pipeline_metadata!(
+ project: child_pipeline.project, auto_cancel_on_new_commit: 'interruptible'
+ )
+ end
+
+ it 'cancels interruptible child pipeline builds' do
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'success')
+
+ execute
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('canceled', 'success')
+ end
+
+ context 'when the FF ci_workflow_auto_cancel_on_new_commit is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_auto_cancel_on_new_commit: false)
+ end
+
+ it 'does not cancel any child pipeline builds' do
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'success')
+
+ execute
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'success')
+ end
+ end
+ end
end
context 'when the child pipeline has non-interruptible non-started job' do
@@ -227,6 +257,37 @@ RSpec.describe Ci::PipelineCreation::CancelRedundantPipelinesService, feature_ca
end
end
+ context 'when there are non-interruptible completed jobs in the pipeline' do
+ before do
+ create(:ci_build, :failed, pipeline: prev_pipeline)
+ create(:ci_build, :success, pipeline: prev_pipeline)
+ end
+
+ it 'does not cancel any job' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly(
+ 'running', 'success', 'created', 'failed', 'success'
+ )
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+
+ context 'when the FF ci_workflow_auto_cancel_on_new_commit is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_auto_cancel_on_new_commit: false)
+ end
+
+ it 'does not cancel any job' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly(
+ 'running', 'success', 'created', 'failed', 'success'
+ )
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+ end
+ end
+
context 'when there are trigger jobs' do
before do
create(:ci_bridge, :created, pipeline: prev_pipeline)
@@ -246,6 +307,152 @@ RSpec.describe Ci::PipelineCreation::CancelRedundantPipelinesService, feature_ca
end
end
+ context 'when auto_cancel_on_new_commit is `interruptible`' do
+ before do
+ prev_pipeline.create_pipeline_metadata!(
+ project: prev_pipeline.project, auto_cancel_on_new_commit: 'interruptible'
+ )
+ end
+
+ it 'cancels only interruptible jobs' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly('canceled', 'success', 'created')
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+
+ context 'when the FF ci_workflow_auto_cancel_on_new_commit is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_auto_cancel_on_new_commit: false)
+ end
+
+ it 'cancels non started builds' do
+ execute
+
+ expect(build_statuses(prev_pipeline)).to contain_exactly('canceled', 'success', 'canceled')
+ expect(build_statuses(pipeline)).to contain_exactly('pending')
+ end
+ end
+
+ context 'when there are non-interruptible completed jobs in the pipeline' do
+ before do
+ create(:ci_build, :failed, pipeline: prev_pipeline)
+ create(:ci_build, :success, pipeline: prev_pipeline)
+ end
+
+ it 'still cancels only interruptible jobs' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly(
+ 'canceled', 'success', 'created', 'failed', 'success'
+ )
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+
+ context 'when the FF ci_workflow_auto_cancel_on_new_commit is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_auto_cancel_on_new_commit: false)
+ end
+
+ it 'does not cancel any job' do
+ execute
+
+ expect(build_statuses(prev_pipeline)).to contain_exactly(
+ 'created', 'success', 'running', 'failed', 'success'
+ )
+ expect(build_statuses(pipeline)).to contain_exactly('pending')
+ end
+ end
+ end
+ end
+
+ context 'when auto_cancel_on_new_commit is `none`' do
+ before do
+ prev_pipeline.create_pipeline_metadata!(
+ project: prev_pipeline.project, auto_cancel_on_new_commit: 'none'
+ )
+ end
+
+ it 'does not cancel any job' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly('running', 'success', 'created')
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+ end
+
+ context 'when auto_cancel_on_new_commit is `conservative`' do
+ before do
+ prev_pipeline.create_pipeline_metadata!(
+ project: prev_pipeline.project, auto_cancel_on_new_commit: 'conservative'
+ )
+ end
+
+ it 'cancels only previous non started builds' do
+ execute
+
+ expect(build_statuses(prev_pipeline)).to contain_exactly('canceled', 'success', 'canceled')
+ expect(build_statuses(pipeline)).to contain_exactly('pending')
+ end
+
+ context 'when the FF ci_workflow_auto_cancel_on_new_commit is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_auto_cancel_on_new_commit: false)
+ end
+
+ it 'cancels only previous non started builds' do
+ execute
+
+ expect(build_statuses(prev_pipeline)).to contain_exactly('canceled', 'success', 'canceled')
+ expect(build_statuses(pipeline)).to contain_exactly('pending')
+ end
+ end
+
+ context 'when there are non-interruptible completed jobs in the pipeline' do
+ before do
+ create(:ci_build, :failed, pipeline: prev_pipeline)
+ create(:ci_build, :success, pipeline: prev_pipeline)
+ end
+
+ it 'does not cancel any job' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly(
+ 'running', 'success', 'created', 'failed', 'success'
+ )
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+
+ context 'when the FF ci_workflow_auto_cancel_on_new_commit is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_auto_cancel_on_new_commit: false)
+ end
+
+ it 'does not cancel any job' do
+ execute
+
+ expect(job_statuses(prev_pipeline)).to contain_exactly(
+ 'running', 'success', 'created', 'failed', 'success'
+ )
+ expect(job_statuses(pipeline)).to contain_exactly('pending')
+ end
+ end
+ end
+ end
+
+ context 'when auto_cancel_on_new_commit is an invalid value' do
+ before do
+ allow(prev_pipeline).to receive(:auto_cancel_on_new_commit).and_return('invalid')
+ relation = Ci::Pipeline.id_in(prev_pipeline.id)
+ allow(relation).to receive(:each).and_yield(prev_pipeline)
+ allow(Ci::Pipeline).to receive(:id_in).and_return(relation)
+ end
+
+ it 'raises an error' do
+ expect { execute }.to raise_error(ArgumentError, 'Unknown auto_cancel_on_new_commit value: invalid')
+ end
+ end
+
it 'does not cancel future pipelines' do
expect(prev_pipeline.id).to be < pipeline.id
expect(build_statuses(pipeline)).to contain_exactly('pending')
diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb
index af151f93dc7..c08b40e9528 100644
--- a/spec/services/members/create_service_spec.rb
+++ b/spec/services/members/create_service_spec.rb
@@ -119,14 +119,34 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_
before do
# validations will fail because we try to invite them to the project as a guest
source.group.add_developer(member)
+ allow(Gitlab::EventStore).to receive(:publish)
end
- it 'triggers the members added and authorizations changed events' do
+ it 'triggers the authorizations changed events' do
expect(Gitlab::EventStore)
- .to receive(:publish)
- .with(an_instance_of(ProjectAuthorizations::AuthorizationsChangedEvent))
+ .to receive(:publish_group)
+ .with(array_including(an_instance_of(ProjectAuthorizations::AuthorizationsAddedEvent)))
.and_call_original
+ execute_service
+ end
+
+ context 'when feature flag "add_policy_approvers_to_rules" is disabled' do
+ before do
+ stub_feature_flags(add_policy_approvers_to_rules: false)
+ end
+
+ it 'triggers the authorizations changed event' do
+ expect(Gitlab::EventStore)
+ .to receive(:publish)
+ .with(an_instance_of(ProjectAuthorizations::AuthorizationsChangedEvent))
+ .and_call_original
+
+ execute_service
+ end
+ end
+
+ it 'triggers the members added event' do
expect(Gitlab::EventStore)
.to receive(:publish)
.with(an_instance_of(Members::MembersAddedEvent))