summaryrefslogtreecommitdiff
path: root/spec/models/ci
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/ci')
-rw-r--r--spec/models/ci/artifact_blob_spec.rb2
-rw-r--r--spec/models/ci/bridge_spec.rb6
-rw-r--r--spec/models/ci/build_dependencies_spec.rb2
-rw-r--r--spec/models/ci/build_metadata_spec.rb31
-rw-r--r--spec/models/ci/build_need_spec.rb20
-rw-r--r--spec/models/ci/build_report_result_spec.rb2
-rw-r--r--spec/models/ci/build_runner_session_spec.rb2
-rw-r--r--spec/models/ci/build_spec.rb97
-rw-r--r--spec/models/ci/build_trace_chunk_spec.rb2
-rw-r--r--spec/models/ci/build_trace_chunks/database_spec.rb2
-rw-r--r--spec/models/ci/build_trace_chunks/fog_spec.rb2
-rw-r--r--spec/models/ci/build_trace_chunks/redis_spec.rb2
-rw-r--r--spec/models/ci/build_trace_section_name_spec.rb2
-rw-r--r--spec/models/ci/build_trace_section_spec.rb2
-rw-r--r--spec/models/ci/build_trace_spec.rb32
-rw-r--r--spec/models/ci/daily_build_group_report_result_spec.rb2
-rw-r--r--spec/models/ci/freeze_period_status_spec.rb2
-rw-r--r--spec/models/ci/group_spec.rb2
-rw-r--r--spec/models/ci/group_variable_spec.rb2
-rw-r--r--spec/models/ci/instance_variable_spec.rb17
-rw-r--r--spec/models/ci/job_artifact_spec.rb125
-rw-r--r--spec/models/ci/job_variable_spec.rb2
-rw-r--r--spec/models/ci/legacy_stage_spec.rb2
-rw-r--r--spec/models/ci/persistent_ref_spec.rb2
-rw-r--r--spec/models/ci/pipeline_config_spec.rb2
-rw-r--r--spec/models/ci/pipeline_message_spec.rb53
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb2
-rw-r--r--spec/models/ci/pipeline_schedule_variable_spec.rb2
-rw-r--r--spec/models/ci/pipeline_spec.rb255
-rw-r--r--spec/models/ci/pipeline_variable_spec.rb2
-rw-r--r--spec/models/ci/processable_spec.rb2
-rw-r--r--spec/models/ci/ref_spec.rb31
-rw-r--r--spec/models/ci/resource_group_spec.rb2
-rw-r--r--spec/models/ci/resource_spec.rb2
-rw-r--r--spec/models/ci/runner_spec.rb42
-rw-r--r--spec/models/ci/sources/pipeline_spec.rb2
-rw-r--r--spec/models/ci/stage_spec.rb4
-rw-r--r--spec/models/ci/trigger_request_spec.rb2
-rw-r--r--spec/models/ci/trigger_spec.rb2
-rw-r--r--spec/models/ci/variable_spec.rb2
40 files changed, 639 insertions, 130 deletions
diff --git a/spec/models/ci/artifact_blob_spec.rb b/spec/models/ci/artifact_blob_spec.rb
index 99983686670..44f895cc1c5 100644
--- a/spec/models/ci/artifact_blob_spec.rb
+++ b/spec/models/ci/artifact_blob_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ArtifactBlob do
+RSpec.describe Ci::ArtifactBlob do
let_it_be(:project) { create(:project, :public) }
let_it_be(:build) { create(:ci_build, :artifacts, project: project) }
let(:entry) { build.artifacts_metadata_entry('other_artifacts_0.1.2/another-subdirectory/banana_sample.gif') }
diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb
index 385261e0ee9..3a459e5897a 100644
--- a/spec/models/ci/bridge_spec.rb
+++ b/spec/models/ci/bridge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Bridge do
+RSpec.describe Ci::Bridge do
let_it_be(:project) { create(:project) }
let_it_be(:target_project) { create(:project, name: 'project', namespace: create(:namespace, name: 'my')) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
@@ -47,8 +47,8 @@ describe Ci::Bridge do
CI_JOB_NAME CI_JOB_STAGE CI_COMMIT_SHA CI_COMMIT_SHORT_SHA
CI_COMMIT_BEFORE_SHA CI_COMMIT_REF_NAME CI_COMMIT_REF_SLUG
CI_PROJECT_ID CI_PROJECT_NAME CI_PROJECT_PATH
- CI_PROJECT_PATH_SLUG CI_PROJECT_NAMESPACE CI_PIPELINE_IID
- CI_CONFIG_PATH CI_PIPELINE_SOURCE CI_COMMIT_MESSAGE
+ CI_PROJECT_PATH_SLUG CI_PROJECT_NAMESPACE CI_PROJECT_ROOT_NAMESPACE
+ CI_PIPELINE_IID CI_CONFIG_PATH CI_PIPELINE_SOURCE CI_COMMIT_MESSAGE
CI_COMMIT_TITLE CI_COMMIT_DESCRIPTION CI_COMMIT_REF_PROTECTED
]
diff --git a/spec/models/ci/build_dependencies_spec.rb b/spec/models/ci/build_dependencies_spec.rb
index 8f2199ac360..4fa1b3eb5a5 100644
--- a/spec/models/ci/build_dependencies_spec.rb
+++ b/spec/models/ci/build_dependencies_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildDependencies do
+RSpec.describe Ci::BuildDependencies do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, :repository) }
diff --git a/spec/models/ci/build_metadata_spec.rb b/spec/models/ci/build_metadata_spec.rb
index 588e5872cc8..e4d71632957 100644
--- a/spec/models/ci/build_metadata_spec.rb
+++ b/spec/models/ci/build_metadata_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildMetadata do
+RSpec.describe Ci::BuildMetadata do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :repository, group: group, build_timeout: 2000) }
@@ -92,4 +92,33 @@ describe Ci::BuildMetadata do
end
end
end
+
+ describe 'validations' do
+ context 'when attributes are valid' do
+ it 'returns no errors' do
+ metadata.secrets = {
+ DATABASE_PASSWORD: {
+ vault: {
+ engine: { name: 'kv-v2', path: 'kv-v2' },
+ path: 'production/db',
+ field: 'password'
+ }
+ }
+ }
+
+ expect(metadata).to be_valid
+ end
+ end
+
+ context 'when data is invalid' do
+ it 'returns errors' do
+ metadata.secrets = { DATABASE_PASSWORD: { vault: {} } }
+
+ aggregate_failures do
+ expect(metadata).to be_invalid
+ expect(metadata.errors.full_messages).to eq(["Secrets must be a valid json schema"])
+ end
+ end
+ end
+ end
end
diff --git a/spec/models/ci/build_need_spec.rb b/spec/models/ci/build_need_spec.rb
index d1186fa981d..43cce073918 100644
--- a/spec/models/ci/build_need_spec.rb
+++ b/spec/models/ci/build_need_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildNeed, model: true do
+RSpec.describe Ci::BuildNeed, model: true do
let(:build_need) { build(:ci_build_need) }
it { is_expected.to belong_to(:build) }
@@ -17,4 +17,22 @@ describe Ci::BuildNeed, model: true do
it { expect(described_class.artifacts).to contain_exactly(with_artifacts) }
end
+
+ describe 'BulkInsertSafe' do
+ let(:ci_build) { build(:ci_build) }
+
+ it "bulk inserts from Ci::Build model" do
+ ci_build.needs_attributes = [
+ { name: "build", artifacts: true },
+ { name: "build2", artifacts: true },
+ { name: "build3", artifacts: true }
+ ]
+
+ expect(described_class).to receive(:bulk_insert!).and_call_original
+
+ BulkInsertableAssociations.with_bulk_insert do
+ ci_build.save!
+ end
+ end
+ end
end
diff --git a/spec/models/ci/build_report_result_spec.rb b/spec/models/ci/build_report_result_spec.rb
index 078b0d100a1..e78f602feef 100644
--- a/spec/models/ci/build_report_result_spec.rb
+++ b/spec/models/ci/build_report_result_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildReportResult do
+RSpec.describe Ci::BuildReportResult do
let(:build_report_result) { build(:ci_build_report_result, :with_junit_success) }
describe 'associations' do
diff --git a/spec/models/ci/build_runner_session_spec.rb b/spec/models/ci/build_runner_session_spec.rb
index 3e520407884..601c6ad26f9 100644
--- a/spec/models/ci/build_runner_session_spec.rb
+++ b/spec/models/ci/build_runner_session_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildRunnerSession, model: true do
+RSpec.describe Ci::BuildRunnerSession, model: true do
let!(:build) { create(:ci_build, :with_runner_session) }
let(:url) { 'https://new.example.com' }
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 6fdd8463329..857b238981b 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Build do
+RSpec.describe Ci::Build do
let_it_be(:user) { create(:user) }
let_it_be(:group, reload: true) { create(:group) }
let_it_be(:project, reload: true) { create(:project, :repository, group: group) }
@@ -1811,6 +1811,50 @@ describe Ci::Build do
end
end
+ describe '.keep_artifacts!' do
+ let!(:build) { create(:ci_build, artifacts_expire_at: Time.current + 7.days) }
+ let!(:builds_for_update) do
+ Ci::Build.where(id: create_list(:ci_build, 3, artifacts_expire_at: Time.current + 7.days).map(&:id))
+ end
+
+ it 'resets expire_at' do
+ builds_for_update.keep_artifacts!
+
+ builds_for_update.each do |build|
+ expect(build.reload.artifacts_expire_at).to be_nil
+ end
+ end
+
+ it 'does not reset expire_at for other builds' do
+ builds_for_update.keep_artifacts!
+
+ expect(build.reload.artifacts_expire_at).to be_present
+ end
+
+ context 'when having artifacts files' do
+ let!(:artifact) { create(:ci_job_artifact, job: build, expire_in: '7 days') }
+ let!(:artifacts_for_update) do
+ builds_for_update.map do |build|
+ create(:ci_job_artifact, job: build, expire_in: '7 days')
+ end
+ end
+
+ it 'resets dependent objects' do
+ builds_for_update.keep_artifacts!
+
+ artifacts_for_update.each do |artifact|
+ expect(artifact.reload.expire_at).to be_nil
+ end
+ end
+
+ it 'does not reset dependent object for other builds' do
+ builds_for_update.keep_artifacts!
+
+ expect(artifact.reload.expire_at).to be_present
+ end
+ end
+ end
+
describe '#keep_artifacts!' do
let(:build) { create(:ci_build, artifacts_expire_at: Time.current + 7.days) }
@@ -2336,6 +2380,7 @@ describe Ci::Build do
{ 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 },
+ { key: 'CI_PROJECT_ROOT_NAMESPACE', value: project.namespace.root_ancestor.path, public: true, masked: false },
{ key: 'CI_PROJECT_URL', value: project.web_url, public: true, masked: false },
{ key: 'CI_PROJECT_VISIBILITY', value: 'private', public: true, masked: false },
{ key: 'CI_PROJECT_REPOSITORY_LANGUAGES', value: project.repository_languages.map(&:name).join(',').downcase, public: true, masked: false },
@@ -2929,19 +2974,6 @@ describe Ci::Build do
it { is_expected.to include(deployment_variable) }
end
- context 'when build has a freeze period' do
- let(:freeze_variable) { { key: 'CI_DEPLOY_FREEZE', value: 'true', masked: false, public: true } }
-
- before do
- expect_next_instance_of(Ci::FreezePeriodStatus) do |freeze_period|
- expect(freeze_period).to receive(:execute)
- .and_return(true)
- end
- end
-
- it { is_expected.to include(freeze_variable) }
- end
-
context 'when project has default CI config path' do
let(:ci_config_path) { { key: 'CI_CONFIG_PATH', value: '.gitlab-ci.yml', public: true, masked: false } }
@@ -3269,17 +3301,6 @@ describe Ci::Build do
expect(build.scoped_variables_hash).not_to include('MY_VAR': 'my value 1')
end
end
-
- context 'when CI instance variables are disabled' do
- before do
- create(:ci_instance_variable, key: 'MY_VAR', value: 'my value 1')
- stub_feature_flags(ci_instance_level_variables: false)
- end
-
- it 'does not include instance level variables' do
- expect(build.scoped_variables_hash).not_to include('MY_VAR': 'my value 1')
- end
- end
end
describe '#any_unmet_prerequisites?' do
@@ -4050,6 +4071,10 @@ describe Ci::Build do
it 'parses blobs and add the results to the terraform report' do
expect { build.collect_terraform_reports!(terraform_reports) }.not_to raise_error
+ terraform_reports.plans.each do |key, hash_value|
+ expect(hash_value.keys).to match_array(%w[create delete job_id job_name job_path update])
+ end
+
expect(terraform_reports.plans).to match(
a_hash_including(
build.id.to_s => a_hash_including(
@@ -4068,9 +4093,19 @@ describe Ci::Build do
create(:ci_job_artifact, :terraform_with_corrupted_data, job: build, project: build.project)
end
- it 'raises an error' do
- expect { build.collect_terraform_reports!(terraform_reports) }.to raise_error(
- Gitlab::Ci::Parsers::Terraform::Tfplan::TfplanParserError
+ it 'adds invalid plan report' do
+ expect { build.collect_terraform_reports!(terraform_reports) }.not_to raise_error
+
+ terraform_reports.plans.each do |key, hash_value|
+ expect(hash_value.keys).to match_array(%w[job_id job_name job_path tf_report_error])
+ end
+
+ expect(terraform_reports.plans).to match(
+ a_hash_including(
+ build.id.to_s => a_hash_including(
+ 'tf_report_error' => :invalid_json_format
+ )
+ )
)
end
end
@@ -4258,15 +4293,15 @@ describe Ci::Build do
end
end
- context 'when `release_steps` feature is required by build' do
+ context 'when `multi_build_steps` feature is required by build' do
before do
expect(build).to receive(:runner_required_feature_names) do
- [:release_steps]
+ [:multi_build_steps]
end
end
context 'when runner provides given feature' do
- let(:runner_features) { { release_steps: true } }
+ let(:runner_features) { { multi_build_steps: true } }
it { is_expected.to be_truthy }
end
diff --git a/spec/models/ci/build_trace_chunk_spec.rb b/spec/models/ci/build_trace_chunk_spec.rb
index 85873847fca..dab523f67ab 100644
--- a/spec/models/ci/build_trace_chunk_spec.rb
+++ b/spec/models/ci/build_trace_chunk_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
+RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
include ExclusiveLeaseHelpers
let_it_be(:build) { create(:ci_build, :running) }
diff --git a/spec/models/ci/build_trace_chunks/database_spec.rb b/spec/models/ci/build_trace_chunks/database_spec.rb
index eb94d7dae38..245625b8046 100644
--- a/spec/models/ci/build_trace_chunks/database_spec.rb
+++ b/spec/models/ci/build_trace_chunks/database_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTraceChunks::Database do
+RSpec.describe Ci::BuildTraceChunks::Database do
let(:data_store) { described_class.new }
describe '#available?' do
diff --git a/spec/models/ci/build_trace_chunks/fog_spec.rb b/spec/models/ci/build_trace_chunks/fog_spec.rb
index b8d78bcd069..7ef3018d87b 100644
--- a/spec/models/ci/build_trace_chunks/fog_spec.rb
+++ b/spec/models/ci/build_trace_chunks/fog_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTraceChunks::Fog do
+RSpec.describe Ci::BuildTraceChunks::Fog do
let(:data_store) { described_class.new }
before do
diff --git a/spec/models/ci/build_trace_chunks/redis_spec.rb b/spec/models/ci/build_trace_chunks/redis_spec.rb
index 6cff33d24fa..c37b8697a4d 100644
--- a/spec/models/ci/build_trace_chunks/redis_spec.rb
+++ b/spec/models/ci/build_trace_chunks/redis_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTraceChunks::Redis, :clean_gitlab_redis_shared_state do
+RSpec.describe Ci::BuildTraceChunks::Redis, :clean_gitlab_redis_shared_state do
let(:data_store) { described_class.new }
describe '#available?' do
diff --git a/spec/models/ci/build_trace_section_name_spec.rb b/spec/models/ci/build_trace_section_name_spec.rb
index 11e2d27ff79..b220e67d48e 100644
--- a/spec/models/ci/build_trace_section_name_spec.rb
+++ b/spec/models/ci/build_trace_section_name_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTraceSectionName, model: true do
+RSpec.describe Ci::BuildTraceSectionName, model: true do
subject { build(:ci_build_trace_section_name) }
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/ci/build_trace_section_spec.rb b/spec/models/ci/build_trace_section_spec.rb
index 5bd3a953ec0..640bd202b3a 100644
--- a/spec/models/ci/build_trace_section_spec.rb
+++ b/spec/models/ci/build_trace_section_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTraceSection, model: true do
+RSpec.describe Ci::BuildTraceSection, model: true do
it { is_expected.to belong_to(:build)}
it { is_expected.to belong_to(:project)}
it { is_expected.to belong_to(:section_name)}
diff --git a/spec/models/ci/build_trace_spec.rb b/spec/models/ci/build_trace_spec.rb
index 2471a6fa827..3beca0565c6 100644
--- a/spec/models/ci/build_trace_spec.rb
+++ b/spec/models/ci/build_trace_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildTrace do
+RSpec.describe Ci::BuildTrace do
let(:build) { build_stubbed(:ci_build) }
let(:state) { nil }
let(:data) { StringIO.new('the-stream') }
@@ -11,7 +11,7 @@ describe Ci::BuildTrace do
Gitlab::Ci::Trace::Stream.new { data }
end
- subject { described_class.new(build: build, stream: stream, state: state, content_format: content_format) }
+ subject { described_class.new(build: build, stream: stream, state: state) }
shared_examples 'delegates methods' do
it { is_expected.to delegate_method(:state).to(:trace) }
@@ -25,29 +25,11 @@ describe Ci::BuildTrace do
it { is_expected.to delegate_method(:complete?).to(:build).with_prefix }
end
- context 'with :json content format' do
- let(:content_format) { :json }
+ it_behaves_like 'delegates methods'
- it_behaves_like 'delegates methods'
-
- it { is_expected.to be_json }
-
- it 'returns formatted trace' do
- expect(subject.trace.lines).to eq([
- { offset: 0, content: [{ text: 'the-stream' }] }
- ])
- end
- end
-
- context 'with :html content format' do
- let(:content_format) { :html }
-
- it_behaves_like 'delegates methods'
-
- it { is_expected.to be_html }
-
- it 'returns formatted trace' do
- expect(subject.trace.html).to eq('<span>the-stream</span>')
- end
+ it 'returns formatted trace' do
+ expect(subject.lines).to eq([
+ { offset: 0, content: [{ text: 'the-stream' }] }
+ ])
end
end
diff --git a/spec/models/ci/daily_build_group_report_result_spec.rb b/spec/models/ci/daily_build_group_report_result_spec.rb
index f2ce1b5775f..059a5b76b9a 100644
--- a/spec/models/ci/daily_build_group_report_result_spec.rb
+++ b/spec/models/ci/daily_build_group_report_result_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::DailyBuildGroupReportResult do
+RSpec.describe Ci::DailyBuildGroupReportResult do
let(:daily_build_group_report_result) { build(:ci_daily_build_group_report_result)}
describe 'associations' do
diff --git a/spec/models/ci/freeze_period_status_spec.rb b/spec/models/ci/freeze_period_status_spec.rb
index b700ec8c45f..831895cb528 100644
--- a/spec/models/ci/freeze_period_status_spec.rb
+++ b/spec/models/ci/freeze_period_status_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Ci::FreezePeriodStatus do
+RSpec.describe Ci::FreezePeriodStatus do
let(:project) { create :project }
# '0 23 * * 5' == "At 23:00 on Friday."", '0 7 * * 1' == "At 07:00 on Monday.""
let(:friday_2300) { '0 23 * * 5' }
diff --git a/spec/models/ci/group_spec.rb b/spec/models/ci/group_spec.rb
index 868382e3756..dc9aee906ea 100644
--- a/spec/models/ci/group_spec.rb
+++ b/spec/models/ci/group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Group do
+RSpec.describe Ci::Group do
let_it_be(:project) { create(:project) }
let!(:jobs) { build_list(:ci_build, 1, :success, project: project) }
diff --git a/spec/models/ci/group_variable_spec.rb b/spec/models/ci/group_variable_spec.rb
index 610db9bf0e5..c8eac4d8765 100644
--- a/spec/models/ci/group_variable_spec.rb
+++ b/spec/models/ci/group_variable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::GroupVariable do
+RSpec.describe Ci::GroupVariable do
subject { build(:ci_group_variable) }
it_behaves_like "CI variable"
diff --git a/spec/models/ci/instance_variable_spec.rb b/spec/models/ci/instance_variable_spec.rb
index 4d69b7ac2f8..344ba5bfafd 100644
--- a/spec/models/ci/instance_variable_spec.rb
+++ b/spec/models/ci/instance_variable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::InstanceVariable do
+RSpec.describe Ci::InstanceVariable do
subject { build(:ci_instance_variable) }
it_behaves_like "CI variable"
@@ -15,21 +15,6 @@ describe Ci::InstanceVariable do
subject { build(:ci_instance_variable) }
end
- context 'with instance level variable feature flag disabled' do
- let(:plan_limits) { create(:plan_limits, :default_plan) }
-
- before do
- stub_feature_flags(ci_instance_level_variables_limit: false)
- plan_limits.update(described_class.limit_name => 1)
- create(:ci_instance_variable)
- end
-
- it 'can create new models exceeding the plan limits', :aggregate_failures do
- expect { subject.save }.to change { described_class.count }
- expect(subject.errors[:base]).to be_empty
- end
- end
-
describe '.unprotected' do
subject { described_class.unprotected }
diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb
index 17e00533ac3..b5f9128b7c5 100644
--- a/spec/models/ci/job_artifact_spec.rb
+++ b/spec/models/ci/job_artifact_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::JobArtifact do
+RSpec.describe Ci::JobArtifact do
let(:artifact) { create(:ci_job_artifact, :archive) }
describe "Associations" do
@@ -110,6 +110,21 @@ describe Ci::JobArtifact do
end
end
+ describe '.associated_file_types_for' do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { Ci::JobArtifact.associated_file_types_for(file_type) }
+
+ where(:file_type, :result) do
+ 'codequality' | %w(codequality)
+ 'quality' | nil
+ end
+
+ with_them do
+ it { is_expected.to eq result }
+ end
+ end
+
describe '.erasable' do
subject { described_class.erasable }
@@ -174,18 +189,6 @@ describe Ci::JobArtifact do
end
end
- describe '.for_ref' do
- let(:first_pipeline) { create(:ci_pipeline, ref: 'first_ref') }
- let(:second_pipeline) { create(:ci_pipeline, ref: 'second_ref', project: first_pipeline.project) }
- let!(:first_artifact) { create(:ci_job_artifact, job: create(:ci_build, pipeline: first_pipeline)) }
- let!(:second_artifact) { create(:ci_job_artifact, job: create(:ci_build, pipeline: second_pipeline)) }
-
- it 'returns job artifacts for a given pipeline ref' do
- expect(described_class.for_ref(first_pipeline.ref, first_pipeline.project.id)).to eq([first_artifact])
- expect(described_class.for_ref(second_pipeline.ref, first_pipeline.project.id)).to eq([second_artifact])
- end
- end
-
describe '.for_job_name' do
it 'returns job artifacts for a given job name' do
first_job = create(:ci_build, name: 'first')
@@ -501,4 +504,100 @@ describe Ci::JobArtifact do
end
end
end
+
+ describe '.file_types' do
+ context 'all file types have corresponding limit' do
+ let_it_be(:plan_limits) { create(:plan_limits) }
+
+ where(:file_type) do
+ described_class.file_types.keys
+ end
+
+ with_them do
+ let(:limit_name) { "#{described_class::PLAN_LIMIT_PREFIX}#{file_type}" }
+
+ it { expect(plan_limits.attributes).to include(limit_name), file_type_limit_failure_message(file_type, limit_name) }
+ end
+ end
+ end
+
+ describe '.max_artifact_size' do
+ let(:build) { create(:ci_build) }
+
+ subject(:max_size) { described_class.max_artifact_size(type: artifact_type, project: build.project) }
+
+ context 'when file type is supported' do
+ let(:project_closest_setting) { 1024 }
+ let(:artifact_type) { 'junit' }
+
+ before do
+ stub_feature_flags(ci_max_artifact_size_per_type: flag_enabled)
+ allow(build.project).to receive(:closest_setting).with(:max_artifacts_size).and_return(project_closest_setting)
+ end
+
+ shared_examples_for 'basing off the project closest setting' do
+ it { is_expected.to eq(project_closest_setting.megabytes.to_i) }
+ end
+
+ shared_examples_for 'basing off the plan limit' do
+ it { is_expected.to eq(max_size_for_type.megabytes.to_i) }
+ end
+
+ context 'and feature flag for custom max size per type is enabled' do
+ let(:flag_enabled) { true }
+ let(:limit_name) { "#{described_class::PLAN_LIMIT_PREFIX}#{artifact_type}" }
+
+ let!(:plan_limits) { create(:plan_limits, :default_plan) }
+
+ context 'and plan limit is disabled for the given artifact type' do
+ before do
+ plan_limits.update!(limit_name => 0)
+ end
+
+ it_behaves_like 'basing off the project closest setting'
+
+ context 'and project closest setting results to zero' do
+ let(:project_closest_setting) { 0 }
+
+ it { is_expected.to eq(0) }
+ end
+ end
+
+ context 'and plan limit is enabled for the given artifact type' do
+ before do
+ plan_limits.update!(limit_name => max_size_for_type)
+ end
+
+ context 'and plan limit is smaller than project setting' do
+ let(:max_size_for_type) { project_closest_setting - 1 }
+
+ it_behaves_like 'basing off the plan limit'
+ end
+
+ context 'and plan limit is smaller than project setting' do
+ let(:max_size_for_type) { project_closest_setting + 1 }
+
+ it_behaves_like 'basing off the project closest setting'
+ end
+ end
+ end
+
+ context 'and feature flag for custom max size per type is disabled' do
+ let(:flag_enabled) { false }
+
+ it_behaves_like 'basing off the project closest setting'
+ end
+ end
+ end
+
+ def file_type_limit_failure_message(type, limit_name)
+ <<~MSG
+ The artifact type `#{type}` is missing its counterpart plan limit which is expected to be named `#{limit_name}`.
+
+ Please refer to https://docs.gitlab.com/ee/development/application_limits.html on how to add new plan limit columns.
+
+ Take note that while existing max size plan limits default to 0, succeeding new limits are recommended to have
+ non-zero default values.
+ MSG
+ end
end
diff --git a/spec/models/ci/job_variable_spec.rb b/spec/models/ci/job_variable_spec.rb
index b94a914c784..4aebd3283f0 100644
--- a/spec/models/ci/job_variable_spec.rb
+++ b/spec/models/ci/job_variable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::JobVariable do
+RSpec.describe Ci::JobVariable do
subject { build(:ci_job_variable) }
it_behaves_like "CI variable"
diff --git a/spec/models/ci/legacy_stage_spec.rb b/spec/models/ci/legacy_stage_spec.rb
index f503fc10c08..c53f6abb037 100644
--- a/spec/models/ci/legacy_stage_spec.rb
+++ b/spec/models/ci/legacy_stage_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::LegacyStage do
+RSpec.describe Ci::LegacyStage do
let(:stage) { build(:ci_stage) }
let(:pipeline) { stage.pipeline }
let(:stage_name) { stage.name }
diff --git a/spec/models/ci/persistent_ref_spec.rb b/spec/models/ci/persistent_ref_spec.rb
index 89dd9b05331..18552317025 100644
--- a/spec/models/ci/persistent_ref_spec.rb
+++ b/spec/models/ci/persistent_ref_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PersistentRef do
+RSpec.describe Ci::PersistentRef do
it 'cleans up persistent refs after pipeline finished' do
pipeline = create(:ci_pipeline, :running)
diff --git a/spec/models/ci/pipeline_config_spec.rb b/spec/models/ci/pipeline_config_spec.rb
index 25f514ee5ab..3d033d33df3 100644
--- a/spec/models/ci/pipeline_config_spec.rb
+++ b/spec/models/ci/pipeline_config_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineConfig, type: :model do
+RSpec.describe Ci::PipelineConfig, type: :model do
it { is_expected.to belong_to(:pipeline) }
it { is_expected.to validate_presence_of(:pipeline) }
diff --git a/spec/models/ci/pipeline_message_spec.rb b/spec/models/ci/pipeline_message_spec.rb
new file mode 100644
index 00000000000..6c97a025625
--- /dev/null
+++ b/spec/models/ci/pipeline_message_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::PipelineMessage do
+ describe 'validations' do
+ subject { described_class.new(pipeline: pipeline, content: content) }
+
+ let(:pipeline) { create(:ci_pipeline) }
+
+ context 'when message content is longer than the limit' do
+ let(:content) { 'x' * (described_class::MAX_CONTENT_LENGTH + 1) }
+
+ it 'is truncated with ellipsis' do
+ subject.save!
+
+ expect(subject.content).to end_with('x...')
+ expect(subject.content.length).to eq(described_class::MAX_CONTENT_LENGTH)
+ end
+ end
+
+ context 'when message is not present' do
+ let(:content) { '' }
+
+ it 'returns an error' do
+ expect(subject.save).to be_falsey
+ expect(subject.errors[:content]).to be_present
+ end
+ end
+
+ context 'when message content is valid' do
+ let(:content) { 'valid message content' }
+
+ it 'is saved with default error severity' do
+ subject.save!
+
+ expect(subject.content).to eq(content)
+ expect(subject.severity).to eq('error')
+ expect(subject).to be_error
+ end
+
+ it 'is persist the defined severity' do
+ subject.severity = :warning
+
+ subject.save!
+
+ expect(subject.content).to eq(content)
+ expect(subject.severity).to eq('warning')
+ expect(subject).to be_warning
+ end
+ end
+ end
+end
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index 4ba70552f01..949d5f7bd04 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineSchedule do
+RSpec.describe Ci::PipelineSchedule do
subject { build(:ci_pipeline_schedule) }
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/ci/pipeline_schedule_variable_spec.rb b/spec/models/ci/pipeline_schedule_variable_spec.rb
index c96a24d5042..fd6b1d3dce0 100644
--- a/spec/models/ci/pipeline_schedule_variable_spec.rb
+++ b/spec/models/ci/pipeline_schedule_variable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineScheduleVariable do
+RSpec.describe Ci::PipelineScheduleVariable do
subject { build(:ci_pipeline_schedule_variable) }
it_behaves_like "CI variable"
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 782a4206c36..ed2466d6413 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Pipeline, :mailer do
+RSpec.describe Ci::Pipeline, :mailer do
include ProjectForksHelper
include StubRequests
@@ -219,6 +219,50 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '.outside_pipeline_family' do
+ subject(:outside_pipeline_family) { described_class.outside_pipeline_family(upstream_pipeline) }
+
+ let(:upstream_pipeline) { create(:ci_pipeline, project: project) }
+ let(:child_pipeline) { create(:ci_pipeline, project: project) }
+
+ let!(:other_pipeline) { create(:ci_pipeline, project: project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: upstream_pipeline),
+ source_project: project,
+ pipeline: child_pipeline,
+ project: project)
+ end
+
+ it 'only returns pipelines outside pipeline family' do
+ expect(outside_pipeline_family).to contain_exactly(other_pipeline)
+ end
+ end
+
+ describe '.before_pipeline' do
+ subject(:before_pipeline) { described_class.before_pipeline(child_pipeline) }
+
+ let!(:older_other_pipeline) { create(:ci_pipeline, project: project) }
+
+ let!(:upstream_pipeline) { create(:ci_pipeline, project: project) }
+ let!(:child_pipeline) { create(:ci_pipeline, project: project) }
+
+ let!(:other_pipeline) { create(:ci_pipeline, project: project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: upstream_pipeline),
+ source_project: project,
+ pipeline: child_pipeline,
+ project: project)
+ end
+
+ it 'only returns older pipelines outside pipeline family' do
+ expect(before_pipeline).to contain_exactly(older_other_pipeline)
+ end
+ end
+
describe '#merge_request?' do
let(:pipeline) { create(:ci_pipeline, merge_request: merge_request) }
let(:merge_request) { create(:merge_request) }
@@ -1488,6 +1532,35 @@ describe Ci::Pipeline, :mailer do
sha: project.commit.sha)
end
+ describe '#lazy_ref_commit' do
+ let(:another) do
+ create(:ci_pipeline,
+ project: project,
+ ref: 'feature',
+ sha: project.commit('feature').sha)
+ end
+
+ let(:unicode) do
+ create(:ci_pipeline,
+ project: project,
+ ref: 'ΓΌ/unicode/multi-byte')
+ end
+
+ it 'returns the latest commit for a ref lazily' do
+ expect(project.repository)
+ .to receive(:list_commits_by_ref_name).once
+ .and_call_original
+
+ pipeline.lazy_ref_commit
+ another.lazy_ref_commit
+ unicode.lazy_ref_commit
+
+ expect(pipeline.lazy_ref_commit.id).to eq pipeline.sha
+ expect(another.lazy_ref_commit.id).to eq another.sha
+ expect(unicode.lazy_ref_commit).to be_nil
+ end
+ end
+
describe '#latest?' do
context 'with latest sha' do
it 'returns true' do
@@ -1496,17 +1569,26 @@ describe Ci::Pipeline, :mailer do
end
context 'with a branch name as the ref' do
- it 'looks up commit with the full ref name' do
- expect(pipeline.project).to receive(:commit).with('refs/heads/master').and_call_original
+ it 'looks up a commit for a branch' do
+ expect(pipeline.ref).to eq 'master'
+ expect(pipeline).to be_latest
+ end
+ end
+
+ context 'with a tag name as a ref' do
+ it 'looks up a commit for a tag' do
+ expect(project.repository.branch_names).not_to include 'v1.0.0'
+ pipeline.update(sha: project.commit('v1.0.0').sha, ref: 'v1.0.0', tag: true)
+
+ expect(pipeline).to be_tag
expect(pipeline).to be_latest
end
end
context 'with not latest sha' do
before do
- pipeline.update(
- sha: project.commit("#{project.default_branch}~1").sha)
+ pipeline.update(sha: project.commit("#{project.default_branch}~1").sha)
end
it 'returns false' do
@@ -1932,6 +2014,23 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '.last_finished_for_ref_id' do
+ let(:project) { create(:project, :repository) }
+ let(:branch) { project.default_branch }
+ let(:ref) { project.ci_refs.take }
+ let(:config_source) { Ci::PipelineEnums.config_sources[:parameter_source] }
+ let!(:pipeline1) { create(:ci_pipeline, :success, project: project, ref: branch) }
+ let!(:pipeline2) { create(:ci_pipeline, :success, project: project, ref: branch) }
+ let!(:pipeline3) { create(:ci_pipeline, :failed, project: project, ref: branch) }
+ let!(:pipeline4) { create(:ci_pipeline, :success, project: project, ref: branch) }
+ let!(:pipeline5) { create(:ci_pipeline, :success, project: project, ref: branch, config_source: config_source) }
+
+ it 'returns the expected pipeline' do
+ result = described_class.last_finished_for_ref_id(ref.id)
+ expect(result).to eq(pipeline4)
+ end
+ end
+
describe '.internal_sources' do
subject { described_class.internal_sources }
@@ -2087,7 +2186,7 @@ describe Ci::Pipeline, :mailer do
it 'raises an exception' do
expect { pipeline.update_legacy_status }
- .to raise_error(HasStatus::UnknownStatusError)
+ .to raise_error(Ci::HasStatus::UnknownStatusError)
end
end
end
@@ -2580,6 +2679,55 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#same_family_pipeline_ids' do
+ subject(:same_family_pipeline_ids) { pipeline.same_family_pipeline_ids }
+
+ context 'when pipeline is not child nor parent' do
+ it 'returns just the pipeline id' do
+ expect(same_family_pipeline_ids).to contain_exactly(pipeline.id)
+ end
+ end
+
+ context 'when pipeline is child' do
+ let(:parent) { create(:ci_pipeline, project: pipeline.project) }
+ let(:sibling) { create(:ci_pipeline, project: pipeline.project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: parent),
+ source_project: parent.project,
+ pipeline: pipeline,
+ project: pipeline.project)
+
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: parent),
+ source_project: parent.project,
+ pipeline: sibling,
+ project: sibling.project)
+ end
+
+ it 'returns parent sibling and self ids' do
+ expect(same_family_pipeline_ids).to contain_exactly(parent.id, pipeline.id, sibling.id)
+ end
+ end
+
+ context 'when pipeline is parent' do
+ let(:child) { create(:ci_pipeline, project: pipeline.project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: pipeline),
+ source_project: pipeline.project,
+ pipeline: child,
+ project: child.project)
+ end
+
+ it 'returns self and child ids' do
+ expect(same_family_pipeline_ids).to contain_exactly(pipeline.id, child.id)
+ end
+ end
+ end
+
describe '#stuck?' do
before do
create(:ci_build, :pending, pipeline: pipeline)
@@ -2602,6 +2750,28 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#add_error_message' do
+ let(:pipeline) { build_stubbed(:ci_pipeline) }
+
+ it 'adds a new pipeline error message' do
+ pipeline.add_error_message('The error message')
+
+ expect(pipeline.messages.map(&:content)).to contain_exactly('The error message')
+ end
+
+ context 'when feature flag ci_store_pipeline_messages is disabled' do
+ before do
+ stub_feature_flags(ci_store_pipeline_messages: false)
+ end
+
+ it ' does not add pipeline error message' do
+ pipeline.add_error_message('The error message')
+
+ expect(pipeline.messages).to be_empty
+ end
+ end
+ end
+
describe '#has_yaml_errors?' do
context 'when yaml_errors is set' do
before do
@@ -2825,6 +2995,16 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#batch_lookup_report_artifact_for_file_type' do
+ context 'with code quality report artifact' do
+ let(:pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }
+
+ it "returns the code quality artifact" do
+ expect(pipeline.batch_lookup_report_artifact_for_file_type(:codequality)).to eq(pipeline.job_artifacts.sample)
+ end
+ end
+ end
+
describe '#latest_report_builds' do
it 'returns build with test artifacts' do
test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
@@ -2891,6 +3071,39 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#test_report_summary' do
+ subject { pipeline.test_report_summary }
+
+ context 'when pipeline has multiple builds with report results' do
+ let(:pipeline) { create(:ci_pipeline, :success, project: project) }
+
+ before do
+ create(:ci_build, :success, :report_results, name: 'rspec', pipeline: pipeline, project: project)
+ create(:ci_build, :success, :report_results, name: 'java', pipeline: pipeline, project: project)
+ end
+
+ it 'returns test report summary with collected data', :aggregate_failures do
+ expect(subject.total_time).to be(0.84)
+ expect(subject.total_count).to be(4)
+ expect(subject.success_count).to be(0)
+ expect(subject.failed_count).to be(0)
+ expect(subject.error_count).to be(4)
+ expect(subject.skipped_count).to be(0)
+ end
+ end
+
+ context 'when pipeline does not have any builds with report results' do
+ it 'returns empty test report sumary', :aggregate_failures do
+ expect(subject.total_time).to be(0)
+ expect(subject.total_count).to be(0)
+ expect(subject.success_count).to be(0)
+ expect(subject.failed_count).to be(0)
+ expect(subject.error_count).to be(0)
+ expect(subject.skipped_count).to be(0)
+ end
+ end
+ end
+
describe '#test_reports' do
subject { pipeline.test_reports }
@@ -3069,6 +3282,32 @@ describe Ci::Pipeline, :mailer do
end
end
end
+
+ context 'when transitioning to success' do
+ context 'when feature is enabled' do
+ before do
+ stub_feature_flags(keep_latest_artifacts_for_ref: true)
+ end
+
+ it 'calls the PipelineSuccessUnlockArtifactsWorker' do
+ expect(Ci::PipelineSuccessUnlockArtifactsWorker).to receive(:perform_async).with(pipeline.id)
+
+ pipeline.succeed!
+ end
+ end
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(keep_latest_artifacts_for_ref: false)
+ end
+
+ it 'does not call the PipelineSuccessUnlockArtifactsWorker' do
+ expect(Ci::PipelineSuccessUnlockArtifactsWorker).not_to receive(:perform_async)
+
+ pipeline.succeed!
+ end
+ end
+ end
end
describe '#default_branch?' do
@@ -3133,8 +3372,8 @@ describe Ci::Pipeline, :mailer do
end
end
- describe '#error_messages' do
- subject { pipeline.error_messages }
+ describe '#full_error_messages' do
+ subject { pipeline.full_error_messages }
before do
pipeline.valid?
diff --git a/spec/models/ci/pipeline_variable_spec.rb b/spec/models/ci/pipeline_variable_spec.rb
index e8c7ce088e2..04fcaab4c2d 100644
--- a/spec/models/ci/pipeline_variable_spec.rb
+++ b/spec/models/ci/pipeline_variable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineVariable do
+RSpec.describe Ci::PipelineVariable do
subject { build(:ci_pipeline_variable) }
it_behaves_like "CI variable"
diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb
index e67f740279b..35764e2bbbe 100644
--- a/spec/models/ci/processable_spec.rb
+++ b/spec/models/ci/processable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Processable do
+RSpec.describe Ci::Processable do
let_it_be(:project) { create(:project) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/models/ci/ref_spec.rb b/spec/models/ci/ref_spec.rb
index 3d75cb63141..fd4742a8ad2 100644
--- a/spec/models/ci/ref_spec.rb
+++ b/spec/models/ci/ref_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Ref do
+RSpec.describe Ci::Ref do
it { is_expected.to belong_to(:project) }
describe '.ensure_for' do
@@ -62,6 +62,35 @@ describe Ci::Ref do
end
end
+ describe '#last_finished_pipeline_id' do
+ let(:pipeline_status) { :running }
+ let(:config_source) { Ci::PipelineEnums.config_sources[:repository_source] }
+ let(:pipeline) { create(:ci_pipeline, pipeline_status, config_source: config_source) }
+ let(:ci_ref) { pipeline.ci_ref }
+
+ context 'when there are no finished pipelines' do
+ it 'returns nil' do
+ expect(ci_ref.last_finished_pipeline_id).to be_nil
+ end
+ end
+
+ context 'when there are finished pipelines' do
+ let(:pipeline_status) { :success }
+
+ it 'returns the pipeline id' do
+ expect(ci_ref.last_finished_pipeline_id).to eq(pipeline.id)
+ end
+
+ context 'when the pipeline is not a ci_source' do
+ let(:config_source) { Ci::PipelineEnums.config_sources[:parameter_source] }
+
+ it 'returns nil' do
+ expect(ci_ref.last_finished_pipeline_id).to be_nil
+ end
+ end
+ end
+ end
+
describe '#update_status_by!' do
subject { ci_ref.update_status_by!(pipeline) }
diff --git a/spec/models/ci/resource_group_spec.rb b/spec/models/ci/resource_group_spec.rb
index ce8b03282bc..9f72d1a82e5 100644
--- a/spec/models/ci/resource_group_spec.rb
+++ b/spec/models/ci/resource_group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ResourceGroup do
+RSpec.describe Ci::ResourceGroup do
describe 'validation' do
it 'valids when key includes allowed character' do
resource_group = build(:ci_resource_group, key: 'test')
diff --git a/spec/models/ci/resource_spec.rb b/spec/models/ci/resource_spec.rb
index 27e512e2c45..90f26ef2b31 100644
--- a/spec/models/ci/resource_spec.rb
+++ b/spec/models/ci/resource_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Resource do
+RSpec.describe Ci::Resource do
describe '.free' do
subject { described_class.free }
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 296240b1602..8247ebf1144 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Runner do
+RSpec.describe Ci::Runner do
it_behaves_like 'having unique enum values'
describe 'validation' do
@@ -713,6 +713,46 @@ describe Ci::Runner do
end
end
+ describe '#belongs_to_more_than_one_project?' do
+ context 'project runner' do
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project) }
+
+ context 'two projects assigned to runner' do
+ let(:runner) { create(:ci_runner, :project, projects: [project1, project2]) }
+
+ it 'returns true' do
+ expect(runner.belongs_to_more_than_one_project?).to be_truthy
+ end
+ end
+
+ context 'one project assigned to runner' do
+ let(:runner) { create(:ci_runner, :project, projects: [project1]) }
+
+ it 'returns false' do
+ expect(runner.belongs_to_more_than_one_project?).to be_falsey
+ end
+ end
+ end
+
+ context 'group runner' do
+ let(:group) { create(:group) }
+ let(:runner) { create(:ci_runner, :group, groups: [group]) }
+
+ it 'returns false' do
+ expect(runner.belongs_to_more_than_one_project?).to be_falsey
+ end
+ end
+
+ context 'shared runner' do
+ let(:runner) { create(:ci_runner, :instance) }
+
+ it 'returns false' do
+ expect(runner.belongs_to_more_than_one_project?).to be_falsey
+ end
+ end
+ end
+
describe '#has_tags?' do
context 'when runner has tags' do
subject { create(:ci_runner, tag_list: ['tag']) }
diff --git a/spec/models/ci/sources/pipeline_spec.rb b/spec/models/ci/sources/pipeline_spec.rb
index 5023747b487..ccf3140650b 100644
--- a/spec/models/ci/sources/pipeline_spec.rb
+++ b/spec/models/ci/sources/pipeline_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Sources::Pipeline do
+RSpec.describe Ci::Sources::Pipeline do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:pipeline) }
diff --git a/spec/models/ci/stage_spec.rb b/spec/models/ci/stage_spec.rb
index a1549532559..3d873a1b9c1 100644
--- a/spec/models/ci/stage_spec.rb
+++ b/spec/models/ci/stage_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Stage, :models do
+RSpec.describe Ci::Stage, :models do
let_it_be(:pipeline) { create(:ci_empty_pipeline) }
let(:stage) { create(:ci_stage_entity, pipeline: pipeline, project: pipeline.project) }
@@ -172,7 +172,7 @@ describe Ci::Stage, :models do
it 'raises an exception' do
expect { stage.update_legacy_status }
- .to raise_error(HasStatus::UnknownStatusError)
+ .to raise_error(Ci::HasStatus::UnknownStatusError)
end
end
end
diff --git a/spec/models/ci/trigger_request_spec.rb b/spec/models/ci/trigger_request_spec.rb
index d04349bec92..0d462741089 100644
--- a/spec/models/ci/trigger_request_spec.rb
+++ b/spec/models/ci/trigger_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::TriggerRequest do
+RSpec.describe Ci::TriggerRequest do
describe 'validation' do
it 'be invalid if saving a variable' do
trigger = build(:ci_trigger_request, variables: { TRIGGER_KEY_1: 'TRIGGER_VALUE_1' } )
diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb
index 5b0815f8156..4ba6c6e50f7 100644
--- a/spec/models/ci/trigger_spec.rb
+++ b/spec/models/ci/trigger_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Trigger do
+RSpec.describe Ci::Trigger do
let(:project) { create :project }
describe 'associations' do
diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb
index 810a0ddfd2e..26a7a2596af 100644
--- a/spec/models/ci/variable_spec.rb
+++ b/spec/models/ci/variable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::Variable do
+RSpec.describe Ci::Variable do
subject { build(:ci_variable) }
it_behaves_like "CI variable"