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_spec.rb')
-rw-r--r--spec/models/ci/build_spec.rb266
1 files changed, 181 insertions, 85 deletions
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index dcf6915a01e..6ad6bb16eb5 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -294,31 +294,28 @@ RSpec.describe Ci::Build do
end
end
- describe '.with_reports' do
- subject { described_class.with_reports(Ci::JobArtifact.test_reports) }
+ describe '.with_artifacts' do
+ subject(:builds) { described_class.with_artifacts(artifact_scope) }
- context 'when build has a test report' do
- let!(:build) { create(:ci_build, :success, :test_reports) }
+ let(:artifact_scope) { Ci::JobArtifact.where(file_type: 'archive') }
- it 'selects the build' do
- is_expected.to eq([build])
- end
- end
+ let!(:build_1) { create(:ci_build, :artifacts) }
+ let!(:build_2) { create(:ci_build, :codequality_reports) }
+ let!(:build_3) { create(:ci_build, :test_reports) }
+ let!(:build_4) { create(:ci_build, :artifacts) }
- context 'when build does not have test reports' do
- let!(:build) { create(:ci_build, :success, :trace_artifact) }
-
- it 'does not select the build' do
- is_expected.to be_empty
- end
+ it 'returns artifacts matching the given scope' do
+ expect(builds).to contain_exactly(build_1, build_4)
end
- context 'when there are multiple builds with test reports' do
- let!(:builds) { create_list(:ci_build, 5, :success, :test_reports) }
+ context 'when there are multiple builds containing artifacts' do
+ before do
+ create_list(:ci_build, 5, :success, :test_reports)
+ end
it 'does not execute a query for selecting job artifact one by one' do
recorded = ActiveRecord::QueryRecorder.new do
- subject.each do |build|
+ builds.each do |build|
build.job_artifacts.map { |a| a.file.exists? }
end
end
@@ -1367,7 +1364,7 @@ RSpec.describe Ci::Build do
before do
allow(Deployments::LinkMergeRequestWorker).to receive(:perform_async)
- allow(Deployments::HooksWorker).to receive(:perform_async)
+ allow(deployment).to receive(:execute_hooks)
end
it 'has deployments record with created status' do
@@ -1423,7 +1420,7 @@ RSpec.describe Ci::Build do
before do
allow(Deployments::UpdateEnvironmentWorker).to receive(:perform_async)
- allow(Deployments::HooksWorker).to receive(:perform_async)
+ allow(deployment).to receive(:execute_hooks)
end
it_behaves_like 'avoid deadlock'
@@ -1509,14 +1506,28 @@ RSpec.describe Ci::Build do
it 'transitions to running and calls webhook' do
freeze_time do
- expect(Deployments::HooksWorker)
- .to receive(:perform_async).with(deployment_id: deployment.id, status_changed_at: Time.current)
+ expect(deployment).to receive(:execute_hooks).with(Time.current)
subject
end
expect(deployment).to be_running
end
+
+ context 'when `deployment_hooks_skip_worker` flag is disabled' do
+ before do
+ stub_feature_flags(deployment_hooks_skip_worker: false)
+ end
+
+ it 'executes Deployments::HooksWorker asynchronously' do
+ freeze_time do
+ expect(Deployments::HooksWorker)
+ .to receive(:perform_async).with(deployment_id: deployment.id, status_changed_at: Time.current)
+
+ subject
+ end
+ end
+ end
end
end
end
@@ -1830,6 +1841,27 @@ RSpec.describe Ci::Build do
end
context 'build is erasable' do
+ context 'when project is undergoing stats refresh' do
+ let!(:build) { create(:ci_build, :test_reports, :trace_artifact, :success, :artifacts) }
+
+ describe '#erase' do
+ before do
+ allow(build.project).to receive(:refreshing_build_artifacts_size?).and_return(true)
+ end
+
+ it 'logs and continues with deleting the artifacts' do
+ expect(Gitlab::ProjectStatsRefreshConflictsLogger).to receive(:warn_artifact_deletion_during_stats_refresh).with(
+ method: 'Ci::Build#erase',
+ project_id: build.project.id
+ )
+
+ build.erase
+
+ expect(build.job_artifacts.count).to eq(0)
+ end
+ end
+ end
+
context 'new artifacts' do
let!(:build) { create(:ci_build, :test_reports, :trace_artifact, :success, :artifacts) }
@@ -1924,6 +1956,23 @@ RSpec.describe Ci::Build do
expect(build.send("job_artifacts_#{file_type}")).not_to be_nil
end
end
+
+ context 'when the project is undergoing stats refresh' do
+ before do
+ allow(build.project).to receive(:refreshing_build_artifacts_size?).and_return(true)
+ end
+
+ it 'logs and continues with deleting the artifacts' do
+ expect(Gitlab::ProjectStatsRefreshConflictsLogger).to receive(:warn_artifact_deletion_during_stats_refresh).with(
+ method: 'Ci::Build#erase_erasable_artifacts!',
+ project_id: build.project.id
+ )
+
+ subject
+
+ expect(build.job_artifacts.erasable).to be_empty
+ end
+ end
end
describe '#first_pending' do
@@ -2757,6 +2806,7 @@ RSpec.describe Ci::Build do
{ key: 'CI_PROJECT_ID', value: project.id.to_s, public: true, masked: false },
{ key: 'CI_PROJECT_NAME', value: project.path, public: true, masked: false },
{ key: 'CI_PROJECT_TITLE', value: project.title, public: true, masked: false },
+ { key: 'CI_PROJECT_DESCRIPTION', value: project.description, public: true, masked: false },
{ key: 'CI_PROJECT_PATH', value: project.full_path, public: true, masked: false },
{ key: 'CI_PROJECT_PATH_SLUG', value: project.full_path_slug, public: true, masked: false },
{ key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true, masked: false },
@@ -3486,7 +3536,7 @@ RSpec.describe Ci::Build do
]
end
- context 'when gitlab-deploy-token exists' do
+ context 'when gitlab-deploy-token exists for project' do
before do
project.deploy_tokens << deploy_token
end
@@ -3496,11 +3546,32 @@ RSpec.describe Ci::Build do
end
end
- context 'when gitlab-deploy-token does not exist' do
+ context 'when gitlab-deploy-token does not exist for project' do
it 'does not include deploy token variables' do
expect(subject.find { |v| v[:key] == 'CI_DEPLOY_USER'}).to be_nil
expect(subject.find { |v| v[:key] == 'CI_DEPLOY_PASSWORD'}).to be_nil
end
+
+ context 'when gitlab-deploy-token exists for group' do
+ before do
+ group.deploy_tokens << deploy_token
+ end
+
+ it 'includes deploy token variables' do
+ is_expected.to include(*deploy_token_variables)
+ end
+
+ context 'when the FF ci_variable_for_group_gitlab_deploy_token is disabled' do
+ before do
+ stub_feature_flags(ci_variable_for_group_gitlab_deploy_token: false)
+ end
+
+ it 'does not include deploy token variables' do
+ expect(subject.find { |v| v[:key] == 'CI_DEPLOY_USER'}).to be_nil
+ expect(subject.find { |v| v[:key] == 'CI_DEPLOY_PASSWORD'}).to be_nil
+ end
+ end
+ end
end
end
@@ -4298,6 +4369,56 @@ RSpec.describe Ci::Build do
end
end
end
+
+ context 'when build is part of parallel build' do
+ let(:build_1) { create(:ci_build, name: 'build 1/2') }
+ let(:test_report) { Gitlab::Ci::Reports::TestReports.new }
+
+ before do
+ build_1.collect_test_reports!(test_report)
+ end
+
+ it 'uses the group name for test suite name' do
+ expect(test_report.test_suites.keys).to contain_exactly('build')
+ end
+
+ context 'when there are more than one parallel builds' do
+ let(:build_2) { create(:ci_build, name: 'build 2/2') }
+
+ before do
+ build_2.collect_test_reports!(test_report)
+ end
+
+ it 'merges the test suite from parallel builds' do
+ expect(test_report.test_suites.keys).to contain_exactly('build')
+ end
+ end
+ end
+
+ context 'when build is part of matrix build' do
+ let(:test_report) { Gitlab::Ci::Reports::TestReports.new }
+ let(:matrix_build_1) { create(:ci_build, :matrix) }
+
+ before do
+ matrix_build_1.collect_test_reports!(test_report)
+ end
+
+ it 'uses the job name for the test suite' do
+ expect(test_report.test_suites.keys).to contain_exactly(matrix_build_1.name)
+ end
+
+ context 'when there are more than one matrix builds' do
+ let(:matrix_build_2) { create(:ci_build, :matrix) }
+
+ before do
+ matrix_build_2.collect_test_reports!(test_report)
+ end
+
+ it 'keeps separate test suites' do
+ expect(test_report.test_suites.keys).to match_array([matrix_build_1.name, matrix_build_2.name])
+ end
+ end
+ end
end
describe '#collect_accessibility_reports!' do
@@ -4355,68 +4476,6 @@ RSpec.describe Ci::Build do
end
end
- describe '#collect_coverage_reports!' do
- subject { build.collect_coverage_reports!(coverage_report) }
-
- let(:coverage_report) { Gitlab::Ci::Reports::CoverageReports.new }
-
- it { expect(coverage_report.files).to eq({}) }
-
- context 'when build has a coverage report' do
- context 'when there is a Cobertura coverage report from simplecov-cobertura' do
- before do
- create(:ci_job_artifact, :cobertura, job: build, project: build.project)
- end
-
- it 'parses blobs and add the results to the coverage report' do
- expect { subject }.not_to raise_error
-
- expect(coverage_report.files.keys).to match_array(['app/controllers/abuse_reports_controller.rb'])
- expect(coverage_report.files['app/controllers/abuse_reports_controller.rb'].count).to eq(23)
- end
- end
-
- context 'when there is a Cobertura coverage report from gocov-xml' do
- before do
- create(:ci_job_artifact, :coverage_gocov_xml, job: build, project: build.project)
- end
-
- it 'parses blobs and add the results to the coverage report' do
- expect { subject }.not_to raise_error
-
- expect(coverage_report.files.keys).to match_array(['auth/token.go', 'auth/rpccredentials.go'])
- expect(coverage_report.files['auth/token.go'].count).to eq(49)
- expect(coverage_report.files['auth/rpccredentials.go'].count).to eq(10)
- end
- end
-
- context 'when there is a Cobertura coverage report with class filename paths not relative to project root' do
- before do
- allow(build.project).to receive(:full_path).and_return('root/javademo')
- allow(build.pipeline).to receive(:all_worktree_paths).and_return(['src/main/java/com/example/javademo/User.java'])
-
- create(:ci_job_artifact, :coverage_with_paths_not_relative_to_project_root, job: build, project: build.project)
- end
-
- it 'parses blobs and add the results to the coverage report with corrected paths' do
- expect { subject }.not_to raise_error
-
- expect(coverage_report.files.keys).to match_array(['src/main/java/com/example/javademo/User.java'])
- end
- end
-
- context 'when there is a corrupted Cobertura coverage report' do
- before do
- create(:ci_job_artifact, :coverage_with_corrupted_data, job: build, project: build.project)
- end
-
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Ci::Parsers::Coverage::Cobertura::InvalidLineInformationError)
- end
- end
- end
- end
-
describe '#collect_codequality_reports!' do
subject(:codequality_report) { build.collect_codequality_reports!(Gitlab::Ci::Reports::CodequalityReports.new) }
@@ -4506,6 +4565,18 @@ RSpec.describe Ci::Build do
end
end
+ describe '#each_report' do
+ let(:report_types) { Ci::JobArtifact::COVERAGE_REPORT_FILE_TYPES }
+
+ let!(:codequality) { create(:ci_job_artifact, :codequality, job: build) }
+ let!(:coverage) { create(:ci_job_artifact, :coverage_gocov_xml, job: build) }
+ let!(:junit) { create(:ci_job_artifact, :junit, job: build) }
+
+ it 'yields job artifact blob that matches the type' do
+ expect { |b| build.each_report(report_types, &b) }.to yield_with_args(coverage.file_type, String, coverage)
+ end
+ end
+
describe '#report_artifacts' do
subject { build.report_artifacts }
@@ -4947,6 +5018,18 @@ RSpec.describe Ci::Build do
build.execute_hooks
end
+
+ context 'with blocked users' do
+ before do
+ allow(build).to receive(:user) { FactoryBot.build(:user, :blocked) }
+ end
+
+ it 'does not call project.execute_hooks' do
+ expect(build.project).not_to receive(:execute_hooks)
+
+ build.execute_hooks
+ end
+ end
end
context 'without project hooks' do
@@ -5410,6 +5493,19 @@ RSpec.describe Ci::Build do
subject
end
+ context 'with deployment' do
+ let(:environment) { create(:environment) }
+ let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
+
+ it 'updates the deployment status', :aggregate_failures do
+ expect(build.deployment).to receive(:sync_status_with).with(build).and_call_original
+
+ subject
+
+ expect(build.deployment.reload.status).to eq("failed")
+ end
+ end
+
context 'with queued builds' do
let(:traits) { [:queued] }