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/lib/gitlab/ci')
-rw-r--r--spec/lib/gitlab/ci/build/image_spec.rb9
-rw-r--r--spec/lib/gitlab/ci/config/entry/image_spec.rb66
-rw-r--r--spec/lib/gitlab/ci/config/entry/pull_policy_spec.rb87
-rw-r--r--spec/lib/gitlab/ci/config/entry/rules/rule/changes_spec.rb81
-rw-r--r--spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/config/external/mapper_spec.rb25
-rw-r--r--spec/lib/gitlab/ci/jwt_spec.rb14
-rw-r--r--spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/limit/rate_limit_spec.rb35
-rw-r--r--spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/reports/coverage_report_generator_spec.rb104
-rw-r--r--spec/lib/gitlab/ci/reports/coverage_report_spec.rb (renamed from spec/lib/gitlab/ci/reports/coverage_reports_spec.rb)16
-rw-r--r--spec/lib/gitlab/ci/runner_upgrade_check_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/status/build/play_spec.rb7
-rw-r--r--spec/lib/gitlab/ci/status/build/scheduled_spec.rb5
-rw-r--r--spec/lib/gitlab/ci/trace/archive_spec.rb71
-rw-r--r--spec/lib/gitlab/ci/variables/builder_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb47
19 files changed, 531 insertions, 70 deletions
diff --git a/spec/lib/gitlab/ci/build/image_spec.rb b/spec/lib/gitlab/ci/build/image_spec.rb
index 630dfcd06bb..8f77a1f60ad 100644
--- a/spec/lib/gitlab/ci/build/image_spec.rb
+++ b/spec/lib/gitlab/ci/build/image_spec.rb
@@ -28,8 +28,14 @@ RSpec.describe Gitlab::Ci::Build::Image do
context 'when image is defined as hash' do
let(:entrypoint) { '/bin/sh' }
+ let(:pull_policy) { %w[always if-not-present] }
- let(:job) { create(:ci_build, options: { image: { name: image_name, entrypoint: entrypoint, ports: [80] } } ) }
+ let(:job) do
+ create(:ci_build, options: { image: { name: image_name,
+ entrypoint: entrypoint,
+ ports: [80],
+ pull_policy: pull_policy } } )
+ end
it 'fabricates an object of the proper class' do
is_expected.to be_kind_of(described_class)
@@ -38,6 +44,7 @@ RSpec.describe Gitlab::Ci::Build::Image do
it 'populates fabricated object with the proper attributes' do
expect(subject.name).to eq(image_name)
expect(subject.entrypoint).to eq(entrypoint)
+ expect(subject.pull_policy).to eq(pull_policy)
end
it 'populates the ports' do
diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb
index e16a9a7a74a..bd1ab5d8c41 100644
--- a/spec/lib/gitlab/ci/config/entry/image_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb
@@ -1,8 +1,16 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
+require 'support/helpers/stubbed_feature'
+require 'support/helpers/stub_feature_flags'
RSpec.describe Gitlab::Ci::Config::Entry::Image do
+ include StubFeatureFlags
+
+ before do
+ stub_feature_flags(ci_docker_image_pull_policy: true)
+ end
+
let(:entry) { described_class.new(config) }
context 'when configuration is a string' do
@@ -43,6 +51,12 @@ RSpec.describe Gitlab::Ci::Config::Entry::Image do
expect(entry.ports).to be_nil
end
end
+
+ describe '#pull_policy' do
+ it "returns nil" do
+ expect(entry.pull_policy).to be_nil
+ end
+ end
end
context 'when configuration is a hash' do
@@ -109,6 +123,56 @@ RSpec.describe Gitlab::Ci::Config::Entry::Image do
end
end
end
+
+ context 'when configuration has pull_policy' do
+ let(:config) { { name: 'image:1.0', pull_policy: 'if-not-present' } }
+
+ describe '#valid?' do
+ it 'is valid' do
+ entry.compose!
+
+ expect(entry).to be_valid
+ end
+
+ context 'when the feature flag ci_docker_image_pull_policy is disabled' do
+ before do
+ stub_feature_flags(ci_docker_image_pull_policy: false)
+ end
+
+ it 'is not valid' do
+ entry.compose!
+
+ expect(entry).not_to be_valid
+ expect(entry.errors).to include('image config contains unknown keys: pull_policy')
+ end
+ end
+ end
+
+ describe '#value' do
+ it "returns value" do
+ entry.compose!
+
+ expect(entry.value).to eq(
+ name: 'image:1.0',
+ pull_policy: ['if-not-present']
+ )
+ end
+
+ context 'when the feature flag ci_docker_image_pull_policy is disabled' do
+ before do
+ stub_feature_flags(ci_docker_image_pull_policy: false)
+ end
+
+ it 'is not valid' do
+ entry.compose!
+
+ expect(entry.value).to eq(
+ name: 'image:1.0'
+ )
+ end
+ end
+ end
+ end
end
context 'when entry value is not correct' do
diff --git a/spec/lib/gitlab/ci/config/entry/pull_policy_spec.rb b/spec/lib/gitlab/ci/config/entry/pull_policy_spec.rb
new file mode 100644
index 00000000000..c35355b10c6
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/pull_policy_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Ci::Config::Entry::PullPolicy do
+ let(:entry) { described_class.new(config) }
+
+ describe '#value' do
+ subject(:value) { entry.value }
+
+ context 'when config value is nil' do
+ let(:config) { nil }
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'when retry value is an empty array' do
+ let(:config) { [] }
+
+ it { is_expected.to eq(nil) }
+ end
+
+ context 'when retry value is string' do
+ let(:config) { "always" }
+
+ it { is_expected.to eq(%w[always]) }
+ end
+
+ context 'when retry value is array' do
+ let(:config) { %w[always if-not-present] }
+
+ it { is_expected.to eq(%w[always if-not-present]) }
+ end
+ end
+
+ describe 'validation' do
+ subject(:valid?) { entry.valid? }
+
+ context 'when retry value is nil' do
+ let(:config) { nil }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when retry value is an empty array' do
+ let(:config) { [] }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when retry value is a hash' do
+ let(:config) { {} }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when retry value is string' do
+ let(:config) { "always" }
+
+ it { is_expected.to eq(true) }
+
+ context 'when it is an invalid policy' do
+ let(:config) { "invalid" }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when it is an empty string' do
+ let(:config) { "" }
+
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ context 'when retry value is array' do
+ let(:config) { %w[always if-not-present] }
+
+ it { is_expected.to eq(true) }
+
+ context 'when config contains an invalid policy' do
+ let(:config) { %w[always invalid] }
+
+ it { is_expected.to eq(false) }
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/rules/rule/changes_spec.rb b/spec/lib/gitlab/ci/config/entry/rules/rule/changes_spec.rb
new file mode 100644
index 00000000000..3ed4a9f263f
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/rules/rule/changes_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule::Changes do
+ let(:factory) do
+ Gitlab::Config::Entry::Factory.new(described_class)
+ .value(config)
+ end
+
+ subject(:entry) { factory.create! }
+
+ before do
+ entry.compose!
+ end
+
+ describe '.new' do
+ context 'when using a string array' do
+ let(:config) { %w[app/ lib/ spec/ other/* paths/**/*.rb] }
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when using an integer array' do
+ let(:config) { [1, 2] }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns errors' do
+ expect(entry.errors).to include(/changes config should be an array of strings/)
+ end
+ end
+
+ context 'when using a string' do
+ let(:config) { 'a regular string' }
+
+ it { is_expected.not_to be_valid }
+
+ it 'reports an error about invalid policy' do
+ expect(entry.errors).to include(/should be an array of strings/)
+ end
+ end
+
+ context 'when using a long array' do
+ let(:config) { ['app/'] * 51 }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns errors' do
+ expect(entry.errors).to include(/has too many entries \(maximum 50\)/)
+ end
+ end
+
+ context 'when clause is empty' do
+ let(:config) {}
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when policy strategy does not match' do
+ let(:config) { 'string strategy' }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns information about errors' do
+ expect(entry.errors)
+ .to include(/should be an array of strings/)
+ end
+ end
+ end
+
+ describe '#value' do
+ subject(:value) { entry.value }
+
+ context 'when using a string array' do
+ let(:config) { %w[app/ lib/ spec/ other/* paths/**/*.rb] }
+
+ it { is_expected.to eq(config) }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb b/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
index 86270788431..89d349efe8f 100644
--- a/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
@@ -18,6 +18,10 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
let(:entry) { factory.create! }
+ before do
+ entry.compose!
+ end
+
describe '.new' do
subject { entry }
@@ -121,7 +125,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
it { is_expected.not_to be_valid }
it 'returns errors' do
- expect(subject.errors).to include(/changes should be an array of strings/)
+ expect(subject.errors).to include(/changes config should be an array of strings/)
end
end
@@ -131,7 +135,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
it { is_expected.not_to be_valid }
it 'returns errors' do
- expect(subject.errors).to include(/changes is too long \(maximum is 50 characters\)/)
+ expect(subject.errors).to include(/changes config has too many entries \(maximum 50\)/)
end
end
@@ -434,6 +438,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
end
describe '.default' do
+ let(:config) {}
+
it 'does not have default value' do
expect(described_class.default).to be_nil
end
diff --git a/spec/lib/gitlab/ci/config/external/mapper_spec.rb b/spec/lib/gitlab/ci/config/external/mapper_spec.rb
index 2d2adf09a42..7e1b31fea6a 100644
--- a/spec/lib/gitlab/ci/config/external/mapper_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/mapper_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
include StubRequests
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:user) { create(:user) }
+ let_it_be(:user) { project.owner }
let(:local_file) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
@@ -34,6 +34,19 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
describe '#process' do
subject(:process) { mapper.process }
+ shared_examples 'logging config file fetch' do |key, count|
+ it 'propagates the pipeline logger' do
+ process
+
+ fetch_content_log_count = mapper
+ .logger
+ .observations_hash
+ .dig(key, 'count')
+
+ expect(fetch_content_log_count).to eq(count)
+ end
+ end
+
context "when single 'include' keyword is defined" do
context 'when the string is a local file' do
let(:values) do
@@ -45,6 +58,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Local))
end
+
+ it_behaves_like 'logging config file fetch', 'config_file_fetch_local_content_duration_s', 1
end
context 'when the key is a local file hash' do
@@ -68,6 +83,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Remote))
end
+
+ it_behaves_like 'logging config file fetch', 'config_file_fetch_remote_content_duration_s', 1
end
context 'when the key is a remote file hash' do
@@ -92,6 +109,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Template))
end
+
+ it_behaves_like 'logging config file fetch', 'config_file_fetch_template_content_duration_s', 1
end
context 'when the key is a hash of file and remote' do
@@ -118,6 +137,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
expect(subject).to contain_exactly(
an_instance_of(Gitlab::Ci::Config::External::File::Project))
end
+
+ it_behaves_like 'logging config file fetch', 'config_file_fetch_project_content_duration_s', 1
end
context "when the key is project's files" do
@@ -131,6 +152,8 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do
an_instance_of(Gitlab::Ci::Config::External::File::Project),
an_instance_of(Gitlab::Ci::Config::External::File::Project))
end
+
+ it_behaves_like 'logging config file fetch', 'config_file_fetch_project_content_duration_s', 2
end
end
diff --git a/spec/lib/gitlab/ci/jwt_spec.rb b/spec/lib/gitlab/ci/jwt_spec.rb
index b0d6f5adfb1..179e2efc0c7 100644
--- a/spec/lib/gitlab/ci/jwt_spec.rb
+++ b/spec/lib/gitlab/ci/jwt_spec.rb
@@ -160,20 +160,8 @@ RSpec.describe Gitlab::Ci::Jwt do
subject(:jwt) { described_class.for_build(build) }
- context 'when ci_jwt_signing_key feature flag is disabled' do
+ context 'when ci_jwt_signing_key is present' do
before do
- stub_feature_flags(ci_jwt_signing_key: false)
-
- allow(Rails.application.secrets).to receive(:openid_connect_signing_key).and_return(rsa_key_data)
- end
-
- it_behaves_like 'generating JWT for build'
- end
-
- context 'when ci_jwt_signing_key feature flag is enabled' do
- before do
- stub_feature_flags(ci_jwt_signing_key: true)
-
stub_application_setting(ci_jwt_signing_key: rsa_key_data)
end
diff --git a/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb b/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb
index 0580cb9922b..a9851d78f48 100644
--- a/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::Ci::Parsers::Coverage::SaxDocument do
subject(:parse_report) { Nokogiri::XML::SAX::Parser.new(described_class.new(coverage_report, project_path, paths)).parse(cobertura) }
describe '#parse!' do
- let(:coverage_report) { Gitlab::Ci::Reports::CoverageReports.new }
+ let(:coverage_report) { Gitlab::Ci::Reports::CoverageReport.new }
let(:project_path) { 'foo/bar' }
let(:paths) { ['app/user.rb'] }
diff --git a/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb b/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb
index 1d361e16aad..e8f1d617cb7 100644
--- a/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::SecretDetection do
end
it "generates expected metadata_version" do
- expect(report.findings.first.metadata_version).to eq('3.0')
+ expect(report.findings.first.metadata_version).to eq('14.1.2')
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/limit/rate_limit_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/limit/rate_limit_spec.rb
index aa8aec2af4a..69d809aee85 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/limit/rate_limit_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/limit/rate_limit_spec.rb
@@ -30,10 +30,8 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Chain::Limit::RateLimit, :freeze_time, :c
context 'when the limit is exceeded' do
before do
- allow(Gitlab::ApplicationRateLimiter).to receive(:rate_limits)
- .and_return(pipelines_create: { threshold: 1, interval: 1.minute })
-
- stub_feature_flags(ci_throttle_pipelines_creation_dry_run: false)
+ stub_application_setting(pipeline_limit_per_project_user_sha: 1)
+ stub_feature_flags(ci_enforce_throttle_pipelines_creation_override: false)
end
it 'does not persist the pipeline' do
@@ -55,7 +53,9 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Chain::Limit::RateLimit, :freeze_time, :c
class: described_class.name,
project_id: project.id,
subscription_plan: project.actual_plan_name,
- commit_sha: command.sha
+ commit_sha: command.sha,
+ throttled: true,
+ throttle_override: false
)
)
@@ -101,9 +101,9 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Chain::Limit::RateLimit, :freeze_time, :c
end
end
- context 'when ci_throttle_pipelines_creation is disabled' do
+ context 'when ci_enforce_throttle_pipelines_creation is disabled' do
before do
- stub_feature_flags(ci_throttle_pipelines_creation: false)
+ stub_feature_flags(ci_enforce_throttle_pipelines_creation: false)
end
it 'does not break the chain' do
@@ -118,16 +118,25 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Chain::Limit::RateLimit, :freeze_time, :c
expect(pipeline.errors).to be_empty
end
- it 'does not log anything' do
- expect(Gitlab::AppJsonLogger).not_to receive(:info)
+ it 'creates a log entry' do
+ expect(Gitlab::AppJsonLogger).to receive(:info).with(
+ a_hash_including(
+ class: described_class.name,
+ project_id: project.id,
+ subscription_plan: project.actual_plan_name,
+ commit_sha: command.sha,
+ throttled: false,
+ throttle_override: false
+ )
+ )
perform
end
end
- context 'when ci_throttle_pipelines_creation_dry_run is enabled' do
+ context 'when ci_enforce_throttle_pipelines_creation_override is enabled' do
before do
- stub_feature_flags(ci_throttle_pipelines_creation_dry_run: true)
+ stub_feature_flags(ci_enforce_throttle_pipelines_creation_override: true)
end
it 'does not break the chain' do
@@ -148,7 +157,9 @@ RSpec.describe ::Gitlab::Ci::Pipeline::Chain::Limit::RateLimit, :freeze_time, :c
class: described_class.name,
project_id: project.id,
subscription_plan: project.actual_plan_name,
- commit_sha: command.sha
+ commit_sha: command.sha,
+ throttled: false,
+ throttle_override: true
)
)
diff --git a/spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb b/spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb
index 5b0917c5c6f..8f727749ee2 100644
--- a/spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb
@@ -4,9 +4,8 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Pipeline::Quota::Deployments do
let_it_be_with_refind(:namespace) { create(:namespace) }
- let_it_be_with_reload(:default_plan) { create(:default_plan) }
let_it_be_with_reload(:project) { create(:project, :repository, namespace: namespace) }
- let_it_be(:plan_limits) { create(:plan_limits, plan: default_plan) }
+ let_it_be(:plan_limits) { create(:plan_limits, :default_plan) }
let(:pipeline) { build_stubbed(:ci_pipeline, project: project) }
diff --git a/spec/lib/gitlab/ci/reports/coverage_report_generator_spec.rb b/spec/lib/gitlab/ci/reports/coverage_report_generator_spec.rb
new file mode 100644
index 00000000000..eec218346c2
--- /dev/null
+++ b/spec/lib/gitlab/ci/reports/coverage_report_generator_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Reports::CoverageReportGenerator, factory_default: :keep do
+ let_it_be(:project) { create_default(:project, :repository).freeze }
+ let_it_be(:pipeline) { build(:ci_pipeline, :with_coverage_reports) }
+
+ describe '#report' do
+ subject { described_class.new(pipeline).report }
+
+ let_it_be(:pipeline) { create(:ci_pipeline, :success) }
+
+ shared_examples 'having a coverage report' do
+ it 'returns coverage reports with collected data' do
+ expected_files = [
+ "auth/token.go",
+ "auth/rpccredentials.go",
+ "app/controllers/abuse_reports_controller.rb"
+ ]
+
+ expect(subject.files.keys).to match_array(expected_files)
+ end
+ end
+
+ context 'when pipeline has multiple builds with coverage reports' do
+ let!(:build_rspec) { create(:ci_build, :success, name: 'rspec', pipeline: pipeline) }
+ let!(:build_golang) { create(:ci_build, :success, name: 'golang', pipeline: pipeline) }
+
+ before do
+ create(:ci_job_artifact, :cobertura, job: build_rspec)
+ create(:ci_job_artifact, :coverage_gocov_xml, job: build_golang)
+ end
+
+ it_behaves_like 'having a coverage report'
+
+ context 'and it is a child pipeline' do
+ let!(:pipeline) { create(:ci_pipeline, :success, child_of: build(:ci_pipeline)) }
+
+ it 'returns empty coverage report' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+
+ context 'when builds are retried' do
+ let!(:build_rspec) { create(:ci_build, :success, name: 'rspec', retried: true, pipeline: pipeline) }
+ let!(:build_golang) { create(:ci_build, :success, name: 'golang', retried: true, pipeline: pipeline) }
+
+ before do
+ create(:ci_job_artifact, :cobertura, job: build_rspec)
+ create(:ci_job_artifact, :coverage_gocov_xml, job: build_golang)
+ end
+
+ it 'does not take retried builds into account' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'when pipeline does not have any builds with coverage reports' do
+ it 'returns empty coverage reports' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'when pipeline has child pipeline with builds that have coverage reports' do
+ let!(:child_pipeline) { create(:ci_pipeline, :success, child_of: pipeline) }
+
+ let!(:build_rspec) { create(:ci_build, :success, name: 'rspec', pipeline: child_pipeline) }
+ let!(:build_golang) { create(:ci_build, :success, name: 'golang', pipeline: child_pipeline) }
+
+ before do
+ create(:ci_job_artifact, :cobertura, job: build_rspec)
+ create(:ci_job_artifact, :coverage_gocov_xml, job: build_golang)
+ end
+
+ it_behaves_like 'having a coverage report'
+
+ context 'when feature flag ci_child_pipeline_coverage_reports is disabled' do
+ before do
+ stub_feature_flags(ci_child_pipeline_coverage_reports: false)
+ end
+
+ it 'returns empty coverage reports' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+
+ context 'when both parent and child pipeline have builds with coverage reports' do
+ let!(:child_pipeline) { create(:ci_pipeline, :success, child_of: pipeline) }
+
+ let!(:build_rspec) { create(:ci_build, :success, name: 'rspec', pipeline: pipeline) }
+ let!(:build_golang) { create(:ci_build, :success, name: 'golang', pipeline: child_pipeline) }
+
+ before do
+ create(:ci_job_artifact, :cobertura, job: build_rspec)
+ create(:ci_job_artifact, :coverage_gocov_xml, job: build_golang)
+ end
+
+ it_behaves_like 'having a coverage report'
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/reports/coverage_reports_spec.rb b/spec/lib/gitlab/ci/reports/coverage_report_spec.rb
index 41ebae863ee..53646f7dfc0 100644
--- a/spec/lib/gitlab/ci/reports/coverage_reports_spec.rb
+++ b/spec/lib/gitlab/ci/reports/coverage_report_spec.rb
@@ -2,11 +2,25 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::Reports::CoverageReports do
+RSpec.describe Gitlab::Ci::Reports::CoverageReport do
let(:coverage_report) { described_class.new }
it { expect(coverage_report.files).to eq({}) }
+ describe '#empty?' do
+ context 'when no file has been added' do
+ it { expect(coverage_report.empty?).to be(true) }
+ end
+
+ context 'when file has been added' do
+ before do
+ coverage_report.add_file('app.rb', { 1 => 0, 2 => 1 })
+ end
+
+ it { expect(coverage_report.empty?).to be(false) }
+ end
+ end
+
describe '#pick' do
before do
coverage_report.add_file('app.rb', { 1 => 0, 2 => 1 })
diff --git a/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb b/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb
index f2b4e7573c0..0353432741b 100644
--- a/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb
+++ b/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb
@@ -51,21 +51,22 @@ RSpec.describe Gitlab::Ci::RunnerUpgradeCheck do
end
end
- context 'with Gitlab::VERSION set to 14.0.123' do
+ context 'with Gitlab::VERSION set to 14.0.1' do
before do
- stub_version('14.0.123', 'deadbeef')
+ stub_version('14.0.1', 'deadbeef')
described_class.instance.reset!
end
context 'with valid params' do
where(:runner_version, :expected_result) do
- 'v14.1.0-rc3' | :not_available # not available since the GitLab instance is still on 14.0.x
- 'v14.1.0~beta.1574.gf6ea9389' | :not_available # suffixes are correctly handled
- 'v14.1.0/1.1.0' | :not_available # suffixes are correctly handled
- 'v14.1.0' | :not_available # not available since the GitLab instance is still on 14.0.x
+ 'v15.0.0' | :not_available # not available since the GitLab instance is still on 14.x and a major version might be incompatible
+ 'v14.1.0-rc3' | :recommended # recommended since even though the GitLab instance is still on 14.0.x, there is a patch release (14.1.1) available which might contain security fixes
+ 'v14.1.0~beta.1574.gf6ea9389' | :recommended # suffixes are correctly handled
+ 'v14.1.0/1.1.0' | :recommended # suffixes are correctly handled
+ 'v14.1.0' | :recommended # recommended since even though the GitLab instance is still on 14.0.x, there is a patch release (14.1.1) available which might contain security fixes
'v14.0.1' | :recommended # recommended upgrade since 14.0.2 is available
- 'v14.0.2' | :not_available # not available since 14.0.2 is the latest 14.0.x release available
+ 'v14.0.2' | :not_available # not available since 14.0.2 is the latest 14.0.x release available within the instance's major.minor version
'v13.10.1' | :available # available upgrade: 14.1.1
'v13.10.1~beta.1574.gf6ea9389' | :available # suffixes are correctly handled
'v13.10.1/1.1.0' | :available # suffixes are correctly handled
diff --git a/spec/lib/gitlab/ci/status/build/play_spec.rb b/spec/lib/gitlab/ci/status/build/play_spec.rb
index bb406623d2f..ade07a54877 100644
--- a/spec/lib/gitlab/ci/status/build/play_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/play_spec.rb
@@ -3,9 +3,10 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Status::Build::Play do
- let(:user) { create(:user) }
- let(:project) { create(:project, :stubbed_repository) }
- let(:build) { create(:ci_build, :manual, project: project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :stubbed_repository) }
+ let_it_be_with_refind(:build) { create(:ci_build, :manual, project: project) }
+
let(:status) { Gitlab::Ci::Status::Core.new(build, user) }
subject { described_class.new(status) }
diff --git a/spec/lib/gitlab/ci/status/build/scheduled_spec.rb b/spec/lib/gitlab/ci/status/build/scheduled_spec.rb
index b0cd1ac4dc5..a9f9b82767e 100644
--- a/spec/lib/gitlab/ci/status/build/scheduled_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/scheduled_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Status::Build::Scheduled do
- let(:user) { create(:user) }
- let(:project) { create(:project, :stubbed_repository) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :stubbed_repository) }
+
let(:build) { create(:ci_build, :scheduled, project: project) }
let(:status) { Gitlab::Ci::Status::Core.new(build, user) }
diff --git a/spec/lib/gitlab/ci/trace/archive_spec.rb b/spec/lib/gitlab/ci/trace/archive_spec.rb
index 5e965f94347..3ae0e5d1f0e 100644
--- a/spec/lib/gitlab/ci/trace/archive_spec.rb
+++ b/spec/lib/gitlab/ci/trace/archive_spec.rb
@@ -29,35 +29,59 @@ RSpec.describe Gitlab::Ci::Trace::Archive do
let(:stream) { StringIO.new(trace, 'rb') }
let(:src_checksum) { Digest::MD5.hexdigest(trace) }
- context 'when the object store is disabled' do
- before do
- stub_artifacts_object_storage(enabled: false)
+ shared_examples 'valid' do
+ it 'does not count as invalid' do
+ subject.execute!(stream)
+
+ expect(metrics)
+ .not_to have_received(:increment_error_counter)
+ .with(error_reason: :archive_invalid_checksum)
end
+ end
- it 'skips validation' do
+ shared_examples 'local checksum only' do
+ it 'generates only local checksum' do
subject.execute!(stream)
+
expect(trace_metadata.checksum).to eq(src_checksum)
expect(trace_metadata.remote_checksum).to be_nil
- expect(metrics)
- .not_to have_received(:increment_error_counter)
- .with(error_reason: :archive_invalid_checksum)
end
end
- context 'with background_upload enabled' do
+ shared_examples 'skips validations' do
+ it_behaves_like 'valid'
+ it_behaves_like 'local checksum only'
+ end
+
+ shared_context 'with FIPS' do
+ context 'with FIPS enabled', :fips_mode do
+ it_behaves_like 'valid'
+
+ it 'does not generate md5 checksums' do
+ subject.execute!(stream)
+
+ expect(trace_metadata.checksum).to be_nil
+ expect(trace_metadata.remote_checksum).to be_nil
+ end
+ end
+ end
+
+ context 'when the object store is disabled' do
before do
- stub_artifacts_object_storage(background_upload: true)
+ stub_artifacts_object_storage(enabled: false)
end
- it 'skips validation' do
- subject.execute!(stream)
+ it_behaves_like 'skips validations'
+ include_context 'with FIPS'
+ end
- expect(trace_metadata.checksum).to eq(src_checksum)
- expect(trace_metadata.remote_checksum).to be_nil
- expect(metrics)
- .not_to have_received(:increment_error_counter)
- .with(error_reason: :archive_invalid_checksum)
+ context 'with background_upload enabled' do
+ before do
+ stub_artifacts_object_storage(background_upload: true)
end
+
+ it_behaves_like 'skips validations'
+ include_context 'with FIPS'
end
context 'with direct_upload enabled' do
@@ -65,27 +89,26 @@ RSpec.describe Gitlab::Ci::Trace::Archive do
stub_artifacts_object_storage(direct_upload: true)
end
- it 'validates the archived trace' do
+ it_behaves_like 'valid'
+
+ it 'checksums match' do
subject.execute!(stream)
expect(trace_metadata.checksum).to eq(src_checksum)
expect(trace_metadata.remote_checksum).to eq(src_checksum)
- expect(metrics)
- .not_to have_received(:increment_error_counter)
- .with(error_reason: :archive_invalid_checksum)
end
context 'when the checksum does not match' do
let(:invalid_remote_checksum) { SecureRandom.hex }
before do
- expect(::Gitlab::Ci::Trace::RemoteChecksum)
+ allow(::Gitlab::Ci::Trace::RemoteChecksum)
.to receive(:new)
.with(an_instance_of(Ci::JobArtifact))
.and_return(double(md5_checksum: invalid_remote_checksum))
end
- it 'validates the archived trace' do
+ it 'counts as invalid' do
subject.execute!(stream)
expect(trace_metadata.checksum).to eq(src_checksum)
@@ -94,7 +117,11 @@ RSpec.describe Gitlab::Ci::Trace::Archive do
.to have_received(:increment_error_counter)
.with(error_reason: :archive_invalid_checksum)
end
+
+ include_context 'with FIPS'
end
+
+ include_context 'with FIPS'
end
end
end
diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb
index e13a0993fa8..b0704ad7f50 100644
--- a/spec/lib/gitlab/ci/variables/builder_spec.rb
+++ b/spec/lib/gitlab/ci/variables/builder_spec.rb
@@ -64,6 +64,8 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
value: project.path },
{ key: 'CI_PROJECT_TITLE',
value: project.title },
+ { key: 'CI_PROJECT_DESCRIPTION',
+ value: project.description },
{ key: 'CI_PROJECT_PATH',
value: project.full_path },
{ key: 'CI_PROJECT_PATH_SLUG',
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 1910057622b..3dd9ca35881 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -7,7 +7,7 @@ module Gitlab
RSpec.describe YamlProcessor do
include StubRequests
- subject { described_class.new(config, user: nil).execute }
+ subject(:processor) { described_class.new(config, user: nil).execute }
shared_examples 'returns errors' do |error_message|
it 'adds a message when an error is encountered' do
@@ -965,6 +965,51 @@ module Gitlab
})
end
end
+
+ context 'when image has pull_policy' do
+ let(:config) do
+ <<~YAML
+ image:
+ name: ruby:2.7
+ pull_policy: if-not-present
+
+ test:
+ script: exit 0
+ YAML
+ end
+
+ it { is_expected.to be_valid }
+
+ it "returns image and service when defined" do
+ expect(processor.stage_builds_attributes("test")).to contain_exactly({
+ stage: "test",
+ stage_idx: 2,
+ name: "test",
+ only: { refs: %w[branches tags] },
+ options: {
+ script: ["exit 0"],
+ image: { name: "ruby:2.7", pull_policy: ["if-not-present"] }
+ },
+ allow_failure: false,
+ when: "on_success",
+ job_variables: [],
+ root_variables_inheritance: true,
+ scheduling_type: :stage
+ })
+ end
+
+ context 'when the feature flag ci_docker_image_pull_policy is disabled' do
+ before do
+ stub_feature_flags(ci_docker_image_pull_policy: false)
+ end
+
+ it { is_expected.not_to be_valid }
+
+ it "returns no job" do
+ expect(processor.jobs).to eq({})
+ end
+ end
+ end
end
describe 'Variables' do