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/models/ci/build_dependencies_spec.rb')
-rw-r--r--spec/models/ci/build_dependencies_spec.rb173
1 files changed, 173 insertions, 0 deletions
diff --git a/spec/models/ci/build_dependencies_spec.rb b/spec/models/ci/build_dependencies_spec.rb
new file mode 100644
index 00000000000..6db69d0f34c
--- /dev/null
+++ b/spec/models/ci/build_dependencies_spec.rb
@@ -0,0 +1,173 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::BuildDependencies do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project, :repository) }
+
+ let_it_be(:pipeline, reload: true) do
+ create(:ci_pipeline, project: project,
+ sha: project.commit.id,
+ ref: project.default_branch,
+ status: 'success')
+ end
+
+ let!(:build) { create(:ci_build, pipeline: pipeline, name: 'build', stage_idx: 0, stage: 'build') }
+ let!(:rspec_test) { create(:ci_build, pipeline: pipeline, name: 'rspec', stage_idx: 1, stage: 'test') }
+ let!(:rubocop_test) { create(:ci_build, pipeline: pipeline, name: 'rubocop', stage_idx: 1, stage: 'test') }
+ let!(:staging) { create(:ci_build, pipeline: pipeline, name: 'staging', stage_idx: 2, stage: 'deploy') }
+
+ describe '#local' do
+ subject { described_class.new(job).local }
+
+ describe 'jobs from previous stages' do
+ context 'when job is in the first stage' do
+ let(:job) { build }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when job is in the second stage' do
+ let(:job) { rspec_test }
+
+ it 'contains all jobs from the first stage' do
+ is_expected.to contain_exactly(build)
+ end
+ end
+
+ context 'when job is in the last stage' do
+ let(:job) { staging }
+
+ it 'contains all jobs from all previous stages' do
+ is_expected.to contain_exactly(build, rspec_test, rubocop_test)
+ end
+
+ context 'when a job is retried' do
+ before do
+ project.add_developer(user)
+ end
+
+ let(:retried_job) { Ci::Build.retry(rspec_test, user) }
+
+ it 'contains the retried job instead of the original one' do
+ is_expected.to contain_exactly(build, retried_job, rubocop_test)
+ end
+ end
+ end
+ end
+
+ describe 'jobs from specified dependencies' do
+ let(:dependencies) { }
+ let(:needs) { }
+
+ let!(:job) do
+ scheduling_type = needs.present? ? :dag : :stage
+
+ create(:ci_build,
+ pipeline: pipeline,
+ name: 'final',
+ scheduling_type: scheduling_type,
+ stage_idx: 3,
+ stage: 'deploy',
+ options: { dependencies: dependencies }
+ )
+ end
+
+ before do
+ needs.to_a.each do |need|
+ create(:ci_build_need, build: job, **need)
+ end
+ end
+
+ context 'when dependencies are defined' do
+ let(:dependencies) { %w(rspec staging) }
+
+ it { is_expected.to contain_exactly(rspec_test, staging) }
+ end
+
+ context 'when needs are defined' do
+ let(:needs) do
+ [
+ { name: 'build', artifacts: true },
+ { name: 'rspec', artifacts: true },
+ { name: 'staging', artifacts: true }
+ ]
+ end
+
+ it { is_expected.to contain_exactly(build, rspec_test, staging) }
+
+ context 'when ci_dag_support is disabled' do
+ before do
+ stub_feature_flags(ci_dag_support: false)
+ end
+
+ it { is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging) }
+ end
+ end
+
+ context 'when need artifacts are defined' do
+ let(:needs) do
+ [
+ { name: 'build', artifacts: true },
+ { name: 'rspec', artifacts: false },
+ { name: 'staging', artifacts: true }
+ ]
+ end
+
+ it { is_expected.to contain_exactly(build, staging) }
+ end
+
+ context 'when needs and dependencies are defined' do
+ let(:dependencies) { %w(rspec staging) }
+ let(:needs) do
+ [
+ { name: 'build', artifacts: true },
+ { name: 'rspec', artifacts: true },
+ { name: 'staging', artifacts: true }
+ ]
+ end
+
+ it { is_expected.to contain_exactly(rspec_test, staging) }
+ end
+
+ context 'when needs and dependencies contradict' do
+ let(:dependencies) { %w(rspec staging) }
+ let(:needs) do
+ [
+ { name: 'build', artifacts: true },
+ { name: 'rspec', artifacts: false },
+ { name: 'staging', artifacts: true }
+ ]
+ end
+
+ it 'returns only the intersection' do
+ is_expected.to contain_exactly(staging)
+ end
+ end
+
+ context 'when nor dependencies or needs are defined' do
+ it 'returns the jobs from previous stages' do
+ is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging)
+ end
+ end
+ end
+ end
+
+ describe '#all' do
+ let!(:job) do
+ create(:ci_build, pipeline: pipeline, name: 'deploy', stage_idx: 3, stage: 'deploy')
+ end
+
+ let(:dependencies) { described_class.new(job) }
+
+ subject { dependencies.all }
+
+ it 'returns the union of all local dependencies and any cross pipeline dependencies' do
+ expect(dependencies).to receive(:local).and_return([1, 2, 3])
+ expect(dependencies).to receive(:cross_pipeline).and_return([3, 4])
+
+ expect(subject).to contain_exactly(1, 2, 3, 4)
+ end
+ end
+end