diff options
Diffstat (limited to 'spec/models/ci')
-rw-r--r-- | spec/models/ci/build_dependencies_spec.rb | 18 | ||||
-rw-r--r-- | spec/models/ci/build_spec.rb | 92 | ||||
-rw-r--r-- | spec/models/ci/build_trace_chunk_spec.rb | 8 | ||||
-rw-r--r-- | spec/models/ci/build_trace_chunks/fog_spec.rb | 51 | ||||
-rw-r--r-- | spec/models/ci/job_artifact_spec.rb | 23 | ||||
-rw-r--r-- | spec/models/ci/job_token/project_scope_link_spec.rb | 18 | ||||
-rw-r--r-- | spec/models/ci/job_token/scope_spec.rb | 4 | ||||
-rw-r--r-- | spec/models/ci/pending_build_spec.rb | 58 | ||||
-rw-r--r-- | spec/models/ci/pipeline_schedule_spec.rb | 9 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 117 | ||||
-rw-r--r-- | spec/models/ci/runner_spec.rb | 14 | ||||
-rw-r--r-- | spec/models/ci/running_build_spec.rb | 5 |
12 files changed, 340 insertions, 77 deletions
diff --git a/spec/models/ci/build_dependencies_spec.rb b/spec/models/ci/build_dependencies_spec.rb index 331ba9953ca..cd330324840 100644 --- a/spec/models/ci/build_dependencies_spec.rb +++ b/spec/models/ci/build_dependencies_spec.rb @@ -55,6 +55,24 @@ RSpec.describe Ci::BuildDependencies do end end end + + context 'when needs refer to jobs from the same stage' do + let(:job) do + create(:ci_build, + pipeline: pipeline, + name: 'dag_job', + scheduling_type: :dag, + stage_idx: 2, + stage: 'deploy' + ) + end + + before do + create(:ci_build_need, build: job, name: 'staging', artifacts: true) + end + + it { is_expected.to contain_exactly(staging) } + end end describe 'jobs from specified dependencies' do diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 62dec522161..0c344270e0b 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -39,6 +39,34 @@ RSpec.describe Ci::Build do it { is_expected.to delegate_method(:merge_request_ref?).to(:pipeline) } it { is_expected.to delegate_method(:legacy_detached_merge_request_pipeline?).to(:pipeline) } + shared_examples 'calling proper BuildFinishedWorker' do + context 'when ci_build_finished_worker_namespace_changed feature flag enabled' do + before do + stub_feature_flags(ci_build_finished_worker_namespace_changed: build.project) + end + + it 'calls Ci::BuildFinishedWorker' do + expect(Ci::BuildFinishedWorker).to receive(:perform_async) + expect(::BuildFinishedWorker).not_to receive(:perform_async) + + subject + end + end + + context 'when ci_build_finished_worker_namespace_changed feature flag disabled' do + before do + stub_feature_flags(ci_build_finished_worker_namespace_changed: false) + end + + it 'calls ::BuildFinishedWorker' do + expect(::BuildFinishedWorker).to receive(:perform_async) + expect(Ci::BuildFinishedWorker).not_to receive(:perform_async) + + subject + end + end + end + describe 'associations' do it 'has a bidirectional relationship with projects' do expect(described_class.reflect_on_association(:project).has_inverse?).to eq(:builds) @@ -384,7 +412,7 @@ RSpec.describe Ci::Build do context 'when there is a queuing entry already present' do before do - ::Ci::PendingBuild.create!(build: build, project: build.project) + create(:ci_pending_build, build: build, project: build.project) end it 'does not raise an error' do @@ -396,7 +424,7 @@ RSpec.describe Ci::Build do context 'when both failure scenario happen at the same time' do before do ::Ci::Build.find(build.id).update_column(:lock_version, 100) - ::Ci::PendingBuild.create!(build: build, project: build.project) + create(:ci_pending_build, build: build, project: build.project) end it 'raises stale object error exception' do @@ -478,7 +506,7 @@ RSpec.describe Ci::Build do let(:build) { create(:ci_build, :pending) } before do - ::Ci::PendingBuild.create!(build: build, project: build.project) + create(:ci_pending_build, build: build, project: build.project) ::Ci::Build.find(build.id).update_column(:lock_version, 100) end @@ -1323,6 +1351,7 @@ RSpec.describe Ci::Build do end it_behaves_like 'avoid deadlock' + it_behaves_like 'calling proper BuildFinishedWorker' it 'transits deployment status to success' do subject @@ -1335,6 +1364,7 @@ RSpec.describe Ci::Build do let(:event) { :drop! } it_behaves_like 'avoid deadlock' + it_behaves_like 'calling proper BuildFinishedWorker' it 'transits deployment status to failed' do subject @@ -1359,6 +1389,7 @@ RSpec.describe Ci::Build do let(:event) { :cancel! } it_behaves_like 'avoid deadlock' + it_behaves_like 'calling proper BuildFinishedWorker' it 'transits deployment status to canceled' do subject @@ -1966,6 +1997,23 @@ RSpec.describe Ci::Build do end end + describe '#tag_list' do + let_it_be(:build) { create(:ci_build, tag_list: ['tag']) } + + context 'when tags are preloaded' do + it 'does not trigger queries' do + build_with_tags = described_class.eager_load_tags.id_in([build]).to_a.first + + expect { build_with_tags.tag_list }.not_to exceed_all_query_limit(0) + expect(build_with_tags.tag_list).to eq(['tag']) + end + end + + context 'when tags are not preloaded' do + it { expect(described_class.find(build.id).tag_list).to eq(['tag']) } + end + end + describe '#has_tags?' do context 'when build has tags' do subject { create(:ci_build, tag_list: ['tag']) } @@ -2155,15 +2203,15 @@ RSpec.describe Ci::Build do end it 'contains options' do - expect(build.options).to eq(options.stringify_keys) + expect(build.options).to eq(options.symbolize_keys) end - it 'allows to access with keys' do + it 'allows to access with symbolized keys' do expect(build.options[:image]).to eq('ruby:2.7') end - it 'allows to access with strings' do - expect(build.options['image']).to eq('ruby:2.7') + it 'rejects access with string keys' do + expect(build.options['image']).to be_nil end context 'when ci_build_metadata_config is set' do @@ -2172,7 +2220,7 @@ RSpec.describe Ci::Build do end it 'persist data in build metadata' do - expect(build.metadata.read_attribute(:config_options)).to eq(options.stringify_keys) + expect(build.metadata.read_attribute(:config_options)).to eq(options.symbolize_keys) end it 'does not persist data in build' do @@ -4476,26 +4524,12 @@ RSpec.describe Ci::Build do it { is_expected.to include(:upload_multiple_artifacts) } end - context 'when artifacts exclude is defined and the is feature enabled' do + context 'when artifacts exclude is defined' do let(:options) do { artifacts: { exclude: %w[something] } } end - context 'when a feature flag is enabled' do - before do - stub_feature_flags(ci_artifacts_exclude: true) - end - - it { is_expected.to include(:artifacts_exclude) } - end - - context 'when a feature flag is disabled' do - before do - stub_feature_flags(ci_artifacts_exclude: false) - end - - it { is_expected.not_to include(:artifacts_exclude) } - end + it { is_expected.to include(:artifacts_exclude) } end end @@ -4712,9 +4746,9 @@ RSpec.describe Ci::Build do describe '#read_metadata_attribute' do let(:build) { create(:ci_build, :degenerated) } - let(:build_options) { { "key" => "build" } } - let(:metadata_options) { { "key" => "metadata" } } - let(:default_options) { { "key" => "default" } } + let(:build_options) { { key: "build" } } + let(:metadata_options) { { key: "metadata" } } + let(:default_options) { { key: "default" } } subject { build.send(:read_metadata_attribute, :options, :config_options, default_options) } @@ -4749,8 +4783,8 @@ RSpec.describe Ci::Build do describe '#write_metadata_attribute' do let(:build) { create(:ci_build, :degenerated) } - let(:options) { { "key" => "new options" } } - let(:existing_options) { { "key" => "existing options" } } + let(:options) { { key: "new options" } } + let(:existing_options) { { key: "existing options" } } subject { build.send(:write_metadata_attribute, :options, :config_options, options) } diff --git a/spec/models/ci/build_trace_chunk_spec.rb b/spec/models/ci/build_trace_chunk_spec.rb index a16453f3d01..b6e128c317c 100644 --- a/spec/models/ci/build_trace_chunk_spec.rb +++ b/spec/models/ci/build_trace_chunk_spec.rb @@ -152,14 +152,6 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state, :clean_git context 'default value' do it { expect(subject).to eq('redis_trace_chunks') } - - context 'when dedicated_redis_trace_chunks is disabled' do - before do - stub_feature_flags(dedicated_redis_trace_chunks: false) - end - - it { expect(subject).to eq('redis') } - end end end diff --git a/spec/models/ci/build_trace_chunks/fog_spec.rb b/spec/models/ci/build_trace_chunks/fog_spec.rb index d9e9533fb26..21dab6fad60 100644 --- a/spec/models/ci/build_trace_chunks/fog_spec.rb +++ b/spec/models/ci/build_trace_chunks/fog_spec.rb @@ -102,6 +102,57 @@ RSpec.describe Ci::BuildTraceChunks::Fog do end end + describe '#append_data' do + let(:initial_data) { (+'😺').force_encoding(Encoding::ASCII_8BIT) } + let(:model) { create(:ci_build_trace_chunk, :fog_with_data, initial_data: initial_data) } + let(:data) { data_store.data(model) } + + context 'when ci_job_trace_force_encode is enabled' do + it 'appends ASCII data' do + data_store.append_data(model, +'hello world', 4) + + expect(data.encoding).to eq(Encoding::ASCII_8BIT) + expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world') + end + + it 'appends UTF-8 data' do + data_store.append_data(model, +'Résumé', 4) + + expect(data.encoding).to eq(Encoding::ASCII_8BIT) + expect(data.force_encoding(Encoding::UTF_8)).to eq("😺Résumé") + end + + context 'when initial data is UTF-8' do + let(:initial_data) { +'😺' } + + it 'appends ASCII data' do + data_store.append_data(model, +'hello world', 4) + + expect(data.encoding).to eq(Encoding::ASCII_8BIT) + expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world') + end + end + end + + context 'when ci_job_trace_force_encode is disabled' do + before do + stub_feature_flags(ci_job_trace_force_encode: false) + end + + it 'appends ASCII data' do + data_store.append_data(model, +'hello world', 4) + + expect(data.encoding).to eq(Encoding::ASCII_8BIT) + expect(data.force_encoding(Encoding::UTF_8)).to eq('😺hello world') + end + + it 'throws an exception when appending UTF-8 data' do + expect(Gitlab::ErrorTracking).to receive(:track_and_raise_exception).and_call_original + expect { data_store.append_data(model, +'Résumé', 4) }.to raise_exception(Encoding::CompatibilityError) + end + end + end + describe '#delete_data' do subject { data_store.delete_data(model) } diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb index 582639b105e..a94a1dd284a 100644 --- a/spec/models/ci/job_artifact_spec.rb +++ b/spec/models/ci/job_artifact_spec.rb @@ -268,6 +268,29 @@ RSpec.describe Ci::JobArtifact do end end + describe '.for_project' do + it 'returns artifacts only for given project(s)', :aggregate_failures do + artifact1 = create(:ci_job_artifact) + artifact2 = create(:ci_job_artifact) + create(:ci_job_artifact) + + expect(described_class.for_project(artifact1.project)).to match_array([artifact1]) + expect(described_class.for_project([artifact1.project, artifact2.project])).to match_array([artifact1, artifact2]) + end + end + + describe 'created_in_time_range' do + it 'returns artifacts created in given time range', :aggregate_failures do + artifact1 = create(:ci_job_artifact, created_at: 1.day.ago) + artifact2 = create(:ci_job_artifact, created_at: 1.month.ago) + artifact3 = create(:ci_job_artifact, created_at: 1.year.ago) + + expect(described_class.created_in_time_range(from: 1.week.ago)).to match_array([artifact1]) + expect(described_class.created_in_time_range(to: 1.week.ago)).to match_array([artifact2, artifact3]) + expect(described_class.created_in_time_range(from: 2.months.ago, to: 1.week.ago)).to match_array([artifact2]) + end + end + describe 'callbacks' do describe '#schedule_background_upload' do subject { create(:ci_job_artifact, :archive) } diff --git a/spec/models/ci/job_token/project_scope_link_spec.rb b/spec/models/ci/job_token/project_scope_link_spec.rb index d18495b9312..dd6a75dfd89 100644 --- a/spec/models/ci/job_token/project_scope_link_spec.rb +++ b/spec/models/ci/job_token/project_scope_link_spec.rb @@ -65,4 +65,22 @@ RSpec.describe Ci::JobToken::ProjectScopeLink do expect(subject).to contain_exactly(target_link) end end + + describe '.for_source_and_target' do + let_it_be(:link) { create(:ci_job_token_project_scope_link, source_project: project) } + + subject { described_class.for_source_and_target(project, target_project) } + + context 'when link is found' do + let(:target_project) { link.target_project } + + it { is_expected.to eq(link) } + end + + context 'when link is not found' do + let(:target_project) { create(:project) } + + it { is_expected.to be_nil } + end + end end diff --git a/spec/models/ci/job_token/scope_spec.rb b/spec/models/ci/job_token/scope_spec.rb index c731a2634f5..4b95adf8476 100644 --- a/spec/models/ci/job_token/scope_spec.rb +++ b/spec/models/ci/job_token/scope_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Ci::JobToken::Scope do - let_it_be(:project) { create(:project) } + let_it_be(:project) { create(:project, ci_job_token_scope_enabled: true).tap(&:save!) } let(:scope) { described_class.new(project) } @@ -29,7 +29,7 @@ RSpec.describe Ci::JobToken::Scope do end end - describe 'includes?' do + describe '#includes?' do subject { scope.includes?(target_project) } context 'when param is the project defining the scope' do diff --git a/spec/models/ci/pending_build_spec.rb b/spec/models/ci/pending_build_spec.rb index c1d4f4b0a5e..b64f3999232 100644 --- a/spec/models/ci/pending_build_spec.rb +++ b/spec/models/ci/pending_build_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Ci::PendingBuild do context 'when another queuing entry exists for given build' do before do - described_class.create!(build: build, project: project, protected: false) + create(:ci_pending_build, build: build, project: project) end it 'returns a build id as a result' do @@ -29,5 +29,61 @@ RSpec.describe Ci::PendingBuild do expect(result.rows.dig(0, 0)).to eq build.id end end + + context 'when project does not have shared runner' do + it 'sets instance_runners_enabled to false' do + described_class.upsert_from_build!(build) + + expect(described_class.last.instance_runners_enabled).to be_falsey + end + end + + context 'when project has shared runner' do + let_it_be(:runner) { create(:ci_runner, :instance) } + + context 'when ci_pending_builds_maintain_shared_runners_data is enabled' do + it 'sets instance_runners_enabled to true' do + described_class.upsert_from_build!(build) + + expect(described_class.last.instance_runners_enabled).to be_truthy + end + + context 'when project is about to be deleted' do + before do + build.project.update!(pending_delete: true) + end + + it 'sets instance_runners_enabled to false' do + described_class.upsert_from_build!(build) + + expect(described_class.last.instance_runners_enabled).to be_falsey + end + end + + context 'when builds are disabled' do + before do + build.project.project_feature.update!(builds_access_level: false) + end + + it 'sets instance_runners_enabled to false' do + described_class.upsert_from_build!(build) + + expect(described_class.last.instance_runners_enabled).to be_falsey + end + end + end + + context 'when ci_pending_builds_maintain_shared_runners_data is disabled' do + before do + stub_feature_flags(ci_pending_builds_maintain_shared_runners_data: false) + end + + it 'sets instance_runners_enabled to false' do + described_class.upsert_from_build!(build) + + expect(described_class.last.instance_runners_enabled).to be_falsey + end + end + end end end diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb index cf73460bf1e..8de3ebb18b9 100644 --- a/spec/models/ci/pipeline_schedule_spec.rb +++ b/spec/models/ci/pipeline_schedule_spec.rb @@ -123,8 +123,15 @@ RSpec.describe Ci::PipelineSchedule do '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0) '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 2.hours.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5) '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) - '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) + '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 10).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) + '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 8).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) '*/5 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 1, 0) | Time.zone.local(2021, 6, 1, 1, 0) + '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 0) + '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 9) + '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0) + '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0) + '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | true | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 45) + '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | false | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 50) end with_them do diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 26fc4b140c1..74a476a6422 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -11,6 +11,10 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do let_it_be(:namespace) { create_default(:namespace).freeze } let_it_be(:project) { create_default(:project, :repository).freeze } + it 'paginates 15 pipeleines per page' do + expect(described_class.default_per_page).to eq(15) + end + it_behaves_like 'having unique enum values' it { is_expected.to belong_to(:project) } @@ -2768,6 +2772,41 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do expect(control2.count).to eq(control1.count + extra_update_queries + extra_generic_commit_status_validation_queries) end end + + context 'when the first try cannot get an exclusive lock' do + let(:retries) { 1 } + + subject(:cancel_running) { pipeline.cancel_running(retries: retries) } + + before do + build = create(:ci_build, :running, pipeline: pipeline) + + allow(pipeline.cancelable_statuses).to receive(:find_in_batches).and_yield([build]) + + call_count = 0 + allow(build).to receive(:cancel).and_wrap_original do |original, *args| + call_count >= retries ? raise(ActiveRecord::StaleObjectError) : original.call(*args) + + call_count += 1 + end + end + + it 'retries again and cancels the build' do + cancel_running + + expect(latest_status).to contain_exactly('canceled') + end + + context 'when the retries parameter is 0' do + let(:retries) { 0 } + + it 'raises error' do + expect do + cancel_running + end.to raise_error(ActiveRecord::StaleObjectError) + end + end + end end describe '#retry_failed' do @@ -2854,7 +2893,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end it 'builds hook data once' do - create(:pipelines_email_service) + create(:pipelines_email_integration) expect(Gitlab::DataBuilder::Pipeline).to receive(:build).once.and_call_original @@ -3772,16 +3811,6 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do it 'can generate a codequality report' do expect(subject).to be_truthy end - - context 'when feature is disabled' do - before do - stub_feature_flags(codequality_mr_diff: false) - end - - it 'can not generate a codequality report' do - expect(subject).to be_falsey - end - end end end @@ -4355,16 +4384,14 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end end - describe '#base_and_ancestors' do - subject { pipeline.base_and_ancestors(same_project: same_project) } + describe '#self_and_upstreams' do + subject(:self_and_upstreams) { pipeline.self_and_upstreams } let_it_be(:pipeline) { create(:ci_pipeline, :created) } - let(:same_project) { false } - context 'when pipeline is not child nor parent' do it 'returns just the pipeline itself' do - expect(subject).to contain_exactly(pipeline) + expect(self_and_upstreams).to contain_exactly(pipeline) end end @@ -4378,7 +4405,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end it 'returns parent and self' do - expect(subject).to contain_exactly(parent, pipeline) + expect(self_and_upstreams).to contain_exactly(parent, pipeline) end end @@ -4390,7 +4417,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end it 'returns self' do - expect(subject).to contain_exactly(pipeline) + expect(self_and_upstreams).to contain_exactly(pipeline) end end @@ -4406,11 +4433,11 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end it 'returns self, parent and ancestor' do - expect(subject).to contain_exactly(ancestor, parent, pipeline) + expect(self_and_upstreams).to contain_exactly(ancestor, parent, pipeline) end end - context 'when pipeline is a triggered pipeline' do + context 'when pipeline is a triggered pipeline from a different project' do let_it_be(:pipeline) { create(:ci_pipeline, :created) } let(:upstream) { create(:ci_pipeline, project: create(:project)) } @@ -4419,18 +4446,41 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do create_source_pipeline(upstream, pipeline) end - context 'same_project: false' do - it 'returns upstream and self' do - expect(subject).to contain_exactly(pipeline, upstream) - end + it 'returns upstream and self' do + expect(self_and_upstreams).to contain_exactly(pipeline, upstream) end + end + end - context 'same_project: true' do - let(:same_project) { true } + describe '#self_and_ancestors' do + subject(:self_and_ancestors) { pipeline.self_and_ancestors } - it 'returns self' do - expect(subject).to contain_exactly(pipeline) - end + context 'when pipeline is child' do + let(:pipeline) { create(:ci_pipeline, :created) } + let(:parent) { create(:ci_pipeline) } + let(:sibling) { create(:ci_pipeline) } + + before do + create_source_pipeline(parent, pipeline) + create_source_pipeline(parent, sibling) + end + + it 'returns parent and self' do + expect(self_and_ancestors).to contain_exactly(parent, pipeline) + end + end + + context 'when pipeline is a triggered pipeline from a different project' do + let_it_be(:pipeline) { create(:ci_pipeline, :created) } + + let(:upstream) { create(:ci_pipeline, project: create(:project)) } + + before do + create_source_pipeline(upstream, pipeline) + end + + it 'returns only self' do + expect(self_and_ancestors).to contain_exactly(pipeline) end end end @@ -4468,15 +4518,18 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end context 'when the parent pipeline has a dependent upstream pipeline' do - let!(:upstream_bridge) do - create_bridge(create(:ci_pipeline, project: create(:project)), parent_pipeline, true) - end + let(:upstream_pipeline) { create(:ci_pipeline, project: create(:project)) } + let!(:upstream_bridge) { create_bridge(upstream_pipeline, parent_pipeline, true) } + + let(:upstream_upstream_pipeline) { create(:ci_pipeline, project: create(:project)) } + let!(:upstream_upstream_bridge) { create_bridge(upstream_upstream_pipeline, upstream_pipeline, true) } it 'marks all source bridges as pending' do reset_bridge expect(bridge.reload).to be_pending expect(upstream_bridge.reload).to be_pending + expect(upstream_upstream_bridge.reload).to be_pending end end end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 61f80bd43b1..ffc8ab4cf8b 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -1086,6 +1086,18 @@ RSpec.describe Ci::Runner do expect(matchers.map(&:tag_list)).to match_array([%w[tag1 tag2], %w[tag3 tag4]]) end end + + context 'with runner_ids' do + before do + create_list(:ci_runner, 2) + end + + it 'includes runner_ids' do + expect(matchers.size).to eq(1) + + expect(matchers.first.runner_ids).to match_array(described_class.all.pluck(:id)) + end + end end describe '#runner_matcher' do @@ -1095,6 +1107,8 @@ RSpec.describe Ci::Runner do subject(:matcher) { runner.runner_matcher } + it { expect(matcher.runner_ids).to eq([runner.id]) } + it { expect(matcher.runner_type).to eq(runner.runner_type) } it { expect(matcher.public_projects_minutes_cost_factor).to eq(runner.public_projects_minutes_cost_factor) } diff --git a/spec/models/ci/running_build_spec.rb b/spec/models/ci/running_build_spec.rb index 589e5a86f4d..629861e35b8 100644 --- a/spec/models/ci/running_build_spec.rb +++ b/spec/models/ci/running_build_spec.rb @@ -21,10 +21,7 @@ RSpec.describe Ci::RunningBuild do context 'when another queuing entry exists for given build' do before do - described_class.create!(build: build, - project: project, - runner: runner, - runner_type: runner.runner_type) + create(:ci_running_build, build: build, project: project, runner: runner) end it 'returns a build id as a result' do |