diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-18 22:00:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-18 22:00:14 +0300 |
commit | 05f0ebba3a2c8ddf39e436f412dc2ab5bf1353b2 (patch) | |
tree | 11d0f2a6ec31c7793c184106cedc2ded3d9a2cc5 /spec/models/ci | |
parent | ec73467c23693d0db63a797d10194da9e72a74af (diff) |
Add latest changes from gitlab-org/gitlab@15-8-stable-eev15.8.0-rc42
Diffstat (limited to 'spec/models/ci')
-rw-r--r-- | spec/models/ci/bridge_spec.rb | 41 | ||||
-rw-r--r-- | spec/models/ci/build_spec.rb | 80 | ||||
-rw-r--r-- | spec/models/ci/job_artifact_spec.rb | 36 | ||||
-rw-r--r-- | spec/models/ci/namespace_mirror_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 17 | ||||
-rw-r--r-- | spec/models/ci/runner_machine_spec.rb | 51 | ||||
-rw-r--r-- | spec/models/ci/runner_spec.rb | 26 | ||||
-rw-r--r-- | spec/models/ci/runner_version_spec.rb | 8 |
8 files changed, 202 insertions, 59 deletions
diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb index 169b00b9c74..70e977e37ba 100644 --- a/spec/models/ci/bridge_spec.rb +++ b/spec/models/ci/bridge_spec.rb @@ -21,8 +21,8 @@ RSpec.describe Ci::Bridge, feature_category: :continuous_integration do { trigger: { project: 'my/project', branch: 'master' } } end - it 'has many sourced pipelines' do - expect(bridge).to have_many(:sourced_pipelines) + it 'has one sourced pipeline' do + expect(bridge).to have_one(:sourced_pipeline) end it_behaves_like 'has ID tokens', :ci_bridge @@ -34,24 +34,6 @@ RSpec.describe Ci::Bridge, feature_category: :continuous_integration do expect(bridge).to have_one(:downstream_pipeline) end - describe '#sourced_pipelines' do - subject { bridge.sourced_pipelines } - - it 'raises error' do - expect { subject }.to raise_error RuntimeError, 'Ci::Bridge does not have sourced_pipelines association' - end - - context 'when ci_bridge_remove_sourced_pipelines is disabled' do - before do - stub_feature_flags(ci_bridge_remove_sourced_pipelines: false) - end - - it 'returns the sourced_pipelines association' do - expect(bridge.sourced_pipelines).to eq([]) - end - end - end - describe '#retryable?' do let(:bridge) { create(:ci_bridge, :success) } @@ -393,25 +375,6 @@ RSpec.describe Ci::Bridge, feature_category: :continuous_integration do { key: 'VAR7', value: 'value7 $VAR1', raw: true } ) end - - context 'when the FF ci_raw_variables_in_yaml_config is disabled' do - before do - stub_feature_flags(ci_raw_variables_in_yaml_config: false) - end - - it 'ignores the raw attribute' do - expect(downstream_variables).to contain_exactly( - { key: 'BRIDGE', value: 'cross' }, - { key: 'VAR1', value: 'value1' }, - { key: 'VAR2', value: 'value2 value1' }, - { key: 'VAR3', value: 'value3 value1' }, - { key: 'VAR4', value: 'value4 value1' }, - { key: 'VAR5', value: 'value5 value1' }, - { key: 'VAR6', value: 'value6 value1' }, - { key: 'VAR7', value: 'value7 value1' } - ) - end - end end end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index c978e33bf54..dd1fbd7d0d5 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1136,6 +1136,19 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration do it do is_expected.to all(a_hash_including(key: a_string_matching(/-protected$/))) end + + context 'and the cache has the `unprotect` option' do + let(:options) do + { cache: [ + { key: "key", paths: ["public"], policy: "pull-push", unprotect: true }, + { key: "key2", paths: ["public"], policy: "pull-push", unprotect: true } + ] } + end + + it do + is_expected.to all(a_hash_including(key: a_string_matching(/-non_protected$/))) + end + end end context 'when pipeline is not on a protected ref' do @@ -3533,6 +3546,52 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration do end end + context 'for the apple_app_store integration' do + let_it_be(:apple_app_store_integration) { create(:apple_app_store_integration) } + + let(:apple_app_store_variables) do + [ + { key: 'APP_STORE_CONNECT_API_KEY_ISSUER_ID', value: apple_app_store_integration.app_store_issuer_id, masked: true, public: false }, + { key: 'APP_STORE_CONNECT_API_KEY_KEY', value: Base64.encode64(apple_app_store_integration.app_store_private_key), masked: true, public: false }, + { key: 'APP_STORE_CONNECT_API_KEY_KEY_ID', value: apple_app_store_integration.app_store_key_id, masked: true, public: false } + ] + end + + context 'when the apple_app_store exists' do + context 'when a build is protected' do + before do + allow(build.pipeline).to receive(:protected_ref?).and_return(true) + build.project.update!(apple_app_store_integration: apple_app_store_integration) + end + + it 'includes apple_app_store variables' do + is_expected.to include(*apple_app_store_variables) + end + end + + context 'when a build is not protected' do + before do + allow(build.pipeline).to receive(:protected_ref?).and_return(false) + build.project.update!(apple_app_store_integration: apple_app_store_integration) + end + + it 'does not include the apple_app_store variables' do + expect(subject.find { |v| v[:key] == 'APP_STORE_CONNECT_API_KEY_ISSUER_ID' }).to be_nil + expect(subject.find { |v| v[:key] == 'APP_STORE_CONNECT_API_KEY_KEY' }).to be_nil + expect(subject.find { |v| v[:key] == 'APP_STORE_CONNECT_API_KEY_KEY_ID' }).to be_nil + end + end + end + + context 'when the apple_app_store integration does not exist' do + it 'does not include apple_app_store variables' do + expect(subject.find { |v| v[:key] == 'APP_STORE_CONNECT_API_KEY_ISSUER_ID' }).to be_nil + expect(subject.find { |v| v[:key] == 'APP_STORE_CONNECT_API_KEY_KEY' }).to be_nil + expect(subject.find { |v| v[:key] == 'APP_STORE_CONNECT_API_KEY_KEY_ID' }).to be_nil + end + end + end + context 'when build has dependency which has dotenv variable' do let!(:prepare) { create(:ci_build, pipeline: pipeline, stage_idx: 0) } let!(:build) { create(:ci_build, pipeline: pipeline, stage_idx: 1, options: { dependencies: [prepare.name] }) } @@ -5664,17 +5723,22 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration do expect(prefix).to eq(ci_testing_partition_id) end + end - context 'when ci_build_partition_id_token_prefix is disabled' do - before do - stub_feature_flags(ci_build_partition_id_token_prefix: false) - end + describe '#remove_token!' do + it 'removes the token' do + expect(build.token).to be_present - it 'does not include partition_id as a token prefix' do - prefix = ci_build.token.split('_').first.to_i(16) + build.remove_token! - expect(prefix).not_to eq(ci_testing_partition_id) - end + expect(build.token).to be_nil + expect(build.changes).to be_empty + end + + it 'does not remove the token when FF is disabled' do + stub_feature_flags(remove_job_token_on_completion: false) + + expect { build.remove_token! }.not_to change(build, :token) end end end diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb index 18aaab1d1f3..a1fd51f60ea 100644 --- a/spec/models/ci/job_artifact_spec.rb +++ b/spec/models/ci/job_artifact_spec.rb @@ -134,6 +134,38 @@ RSpec.describe Ci::JobArtifact do end end + describe 'artifacts_public?' do + subject { artifact.public_access? } + + context 'when job artifact created by default' do + let!(:artifact) { create(:ci_job_artifact) } + + it { is_expected.to be_truthy } + end + + context 'when job artifact created as public' do + let!(:artifact) { create(:ci_job_artifact, :public) } + + it { is_expected.to be_truthy } + end + + context 'when job artifact created as private' do + let!(:artifact) { build(:ci_job_artifact, :private) } + + it { is_expected.to be_falsey } + + context 'and the non_public_artifacts feature flag is disabled' do + let!(:artifact) { build(:ci_job_artifact, :private) } + + before do + stub_feature_flags(non_public_artifacts: false) + end + + it { is_expected.to be_truthy } + end + end + end + describe '.file_types_for_report' do it 'returns the report file types for the report type' do expect(described_class.file_types_for_report(:test)).to match_array(%w[junit]) @@ -690,8 +722,8 @@ RSpec.describe Ci::JobArtifact do end it 'updates project statistics' do - expect(ProjectStatistics).to receive(:increment_statistic).once - .with(project, :build_artifacts_size, -job_artifact.file.size) + expect(ProjectStatistics).to receive(:bulk_increment_statistic).once + .with(project, :build_artifacts_size, [have_attributes(amount: -job_artifact.file.size)]) pipeline.destroy! end diff --git a/spec/models/ci/namespace_mirror_spec.rb b/spec/models/ci/namespace_mirror_spec.rb index 29447cbc89d..63e6e9e6b26 100644 --- a/spec/models/ci/namespace_mirror_spec.rb +++ b/spec/models/ci/namespace_mirror_spec.rb @@ -96,7 +96,7 @@ RSpec.describe Ci::NamespaceMirror do describe '.by_namespace_id' do subject(:result) { described_class.by_namespace_id(group2.id) } - it 'returns namesapce mirrors of namespace id' do + it 'returns namespace mirrors of namespace id' do expect(result).to contain_exactly(group2.ci_namespace_mirror) end end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index b72693d9994..5888f9d109c 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do +RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category: :continuous_integration do include ProjectForksHelper include StubRequests include Ci::SourcePipelineHelpers @@ -1322,6 +1322,21 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end end + context 'when tag is not found' do + let(:pipeline) do + create(:ci_pipeline, project: project, ref: 'not_found_tag', tag: true) + end + + it 'does not expose tag variables' do + expect(subject.to_hash.keys) + .not_to include( + 'CI_COMMIT_TAG', + 'CI_COMMIT_TAG_MESSAGE', + 'CI_BUILD_TAG' + ) + end + end + context 'without a commit' do let(:pipeline) { build(:ci_empty_pipeline, :created, sha: nil) } diff --git a/spec/models/ci/runner_machine_spec.rb b/spec/models/ci/runner_machine_spec.rb new file mode 100644 index 00000000000..e39f987110f --- /dev/null +++ b/spec/models/ci/runner_machine_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::RunnerMachine, feature_category: :runner_fleet, type: :model do + it_behaves_like 'having unique enum values' + + it { is_expected.to belong_to(:runner) } + + describe 'validation' do + it { is_expected.to validate_presence_of(:runner) } + it { is_expected.to validate_presence_of(:machine_xid) } + it { is_expected.to validate_length_of(:machine_xid).is_at_most(64) } + it { is_expected.to validate_length_of(:version).is_at_most(2048) } + it { is_expected.to validate_length_of(:revision).is_at_most(255) } + it { is_expected.to validate_length_of(:platform).is_at_most(255) } + it { is_expected.to validate_length_of(:architecture).is_at_most(255) } + it { is_expected.to validate_length_of(:ip_address).is_at_most(1024) } + + context 'when runner has config' do + it 'is valid' do + runner_machine = build(:ci_runner_machine, config: { gpus: "all" }) + + expect(runner_machine).to be_valid + end + end + + context 'when runner has an invalid config' do + it 'is invalid' do + runner_machine = build(:ci_runner_machine, config: { test: 1 }) + + expect(runner_machine).not_to be_valid + end + end + end + + describe '.stale', :freeze_time do + subject { described_class.stale.ids } + + let!(:runner_machine1) { create(:ci_runner_machine, created_at: 8.days.ago, contacted_at: 7.days.ago) } + let!(:runner_machine2) { create(:ci_runner_machine, created_at: 7.days.ago, contacted_at: nil) } + let!(:runner_machine3) { create(:ci_runner_machine, created_at: 5.days.ago, contacted_at: nil) } + let!(:runner_machine4) do + create(:ci_runner_machine, created_at: (7.days - 1.second).ago, contacted_at: (7.days - 1.second).ago) + end + + it 'returns stale runner machines' do + is_expected.to match_array([runner_machine1.id, runner_machine2.id]) + end + end +end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 803b766c822..b7c7b67b98f 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -11,6 +11,13 @@ RSpec.describe Ci::Runner, feature_category: :runner do let(:factory_name) { :ci_runner } end + context 'loose foreign key on ci_runners.creator_id' do + it_behaves_like 'cleanup by a loose foreign key' do + let!(:parent) { create(:user) } + let!(:model) { create(:ci_runner, creator: parent) } + end + end + describe 'groups association' do # Due to other associations such as projects this whole spec is allowed to # generate cross-database queries. So we have this temporary spec to @@ -530,7 +537,7 @@ RSpec.describe Ci::Runner, feature_category: :runner do end end - describe '.stale' do + describe '.stale', :freeze_time do subject { described_class.stale } let!(:runner1) { create(:ci_runner, :instance, created_at: 4.months.ago, contacted_at: 3.months.ago + 10.seconds) } @@ -1090,6 +1097,23 @@ RSpec.describe Ci::Runner, feature_category: :runner do expect(runner.runner_version).to be_nil end + + context 'with only ip_address specified', :freeze_time do + subject(:heartbeat) do + runner.heartbeat(ip_address: '1.1.1.1') + end + + it 'updates only ip_address' do + attrs = Gitlab::Json.dump(ip_address: '1.1.1.1', contacted_at: Time.current) + + Gitlab::Redis::Cache.with do |redis| + redis_key = runner.send(:cache_attribute_key) + expect(redis).to receive(:set).with(redis_key, attrs, any_args) + end + + heartbeat + end + end end context 'when database was not updated recently' do diff --git a/spec/models/ci/runner_version_spec.rb b/spec/models/ci/runner_version_spec.rb index 552b271fe85..dfaa2201859 100644 --- a/spec/models/ci/runner_version_spec.rb +++ b/spec/models/ci/runner_version_spec.rb @@ -35,12 +35,6 @@ RSpec.describe Ci::RunnerVersion, feature_category: :runner_fleet do end describe 'validation' do - context 'when runner version is too long' do - let(:runner_version) { build(:ci_runner_version, version: 'a' * 2049) } - - it 'is not valid' do - expect(runner_version).to be_invalid - end - end + it { is_expected.to validate_length_of(:version).is_at_most(2048) } end end |