diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
commit | aee0a117a889461ce8ced6fcf73207fe017f1d99 (patch) | |
tree | 891d9ef189227a8445d83f35c1b0fc99573f4380 /spec/services/ci/create_pipeline_service/tags_spec.rb | |
parent | 8d46af3258650d305f53b819eabf7ab18d22f59e (diff) |
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'spec/services/ci/create_pipeline_service/tags_spec.rb')
-rw-r--r-- | spec/services/ci/create_pipeline_service/tags_spec.rb | 173 |
1 files changed, 167 insertions, 6 deletions
diff --git a/spec/services/ci/create_pipeline_service/tags_spec.rb b/spec/services/ci/create_pipeline_service/tags_spec.rb index 335d35010c8..cbbeb870c5f 100644 --- a/spec/services/ci/create_pipeline_service/tags_spec.rb +++ b/spec/services/ci/create_pipeline_service/tags_spec.rb @@ -7,16 +7,15 @@ RSpec.describe Ci::CreatePipelineService do let_it_be(:user) { project.owner } let(:ref) { 'refs/heads/master' } - let(:source) { :push } let(:service) { described_class.new(project, user, { ref: ref }) } - let(:pipeline) { service.execute(source).payload } + let(:pipeline) { create_pipeline } before do - stub_ci_pipeline_yaml_file(config) + stub_yaml_config(config) end context 'with valid config' do - let(:config) { YAML.dump({ test: { script: 'ls', tags: %w[tag1 tag2] } }) } + let(:config) { { test: { script: 'ls', tags: %w[tag1 tag2] } } } it 'creates a pipeline', :aggregate_failures do expect(pipeline).to be_created_successfully @@ -25,8 +24,8 @@ RSpec.describe Ci::CreatePipelineService do end context 'with too many tags' do - let(:tags) { Array.new(50) {|i| "tag-#{i}" } } - let(:config) { YAML.dump({ test: { script: 'ls', tags: tags } }) } + let(:tags) { build_tag_list(label: 'custom', size: 50) } + let(:config) { { test: { script: 'ls', tags: tags } } } it 'creates a pipeline without builds', :aggregate_failures do expect(pipeline).not_to be_created_successfully @@ -34,5 +33,167 @@ RSpec.describe Ci::CreatePipelineService do expect(pipeline.yaml_errors).to eq("jobs:test:tags config must be less than the limit of #{Gitlab::Ci::Config::Entry::Tags::TAGS_LIMIT} tags") end end + + context 'tags persistence' do + let(:config) do + { + build: { + script: 'ls', + stage: 'build', + tags: build_tag_list(label: 'build') + }, + test: { + script: 'ls', + stage: 'test', + tags: build_tag_list(label: 'test') + } + } + end + + let(:config_without_tags) do + config.transform_values { |job| job.except(:tags) } + end + + context 'with multiple tags' do + context 'when the tags do not exist' do + it 'does not execute N+1 queries' do + stub_yaml_config(config_without_tags) + + # warm up the cached objects so we get a more accurate count + create_pipeline + + control = ActiveRecord::QueryRecorder.new(skip_cached: false) do + create_pipeline + end + + stub_yaml_config(config) + + # 2 select tags.* + # 1 insert tags + # 1 insert taggings + tags_queries_size = 4 + + expect { pipeline } + .not_to exceed_all_query_limit(control) + .with_threshold(tags_queries_size) + + expect(pipeline).to be_created_successfully + end + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(ci_bulk_insert_tags: false) + end + + it 'executes N+1s queries' do + stub_yaml_config(config_without_tags) + + # warm up the cached objects so we get a more accurate count + create_pipeline + + control = ActiveRecord::QueryRecorder.new(skip_cached: false) do + create_pipeline + end + + stub_yaml_config(config) + + expect { pipeline } + .to exceed_all_query_limit(control) + .with_threshold(4) + + expect(pipeline).to be_created_successfully + end + end + + context 'when tags are already persisted' do + it 'does not execute N+1 queries' do + # warm up the cached objects so we get a more accurate count + # and insert the tags + create_pipeline + + control = ActiveRecord::QueryRecorder.new(skip_cached: false) do + create_pipeline + end + + # 1 select tags.* + # 1 insert taggings + tags_queries_size = 2 + + expect { pipeline } + .not_to exceed_all_query_limit(control) + .with_threshold(tags_queries_size) + + expect(pipeline).to be_created_successfully + end + end + end + + context 'with bridge jobs' do + let(:config) do + { + test_1: { + script: 'ls', + stage: 'test', + tags: build_tag_list(label: 'test_1') + }, + test_2: { + script: 'ls', + stage: 'test', + tags: build_tag_list(label: '$CI_JOB_NAME') + }, + test_3: { + script: 'ls', + stage: 'test', + tags: build_tag_list(label: 'test_1') + build_tag_list(label: 'test_2') + }, + test_4: { + script: 'ls', + stage: 'test' + }, + deploy: { + stage: 'deploy', + trigger: 'my/project' + } + } + end + + it do + expect(pipeline).to be_created_successfully + expect(pipeline.bridges.size).to eq(1) + expect(pipeline.builds.size).to eq(4) + + expect(tags_for('test_1')) + .to have_attributes(count: 5) + .and all(match(/test_1-tag-\d+/)) + + expect(tags_for('test_2')) + .to have_attributes(count: 5) + .and all(match(/test_2-tag-\d+/)) + + expect(tags_for('test_3')) + .to have_attributes(count: 10) + .and all(match(/test_[1,2]-tag-\d+/)) + + expect(tags_for('test_4')).to be_empty + end + end + end + end + + def tags_for(build_name) + pipeline.builds.find_by_name(build_name).tag_list + end + + def stub_yaml_config(config) + stub_ci_pipeline_yaml_file(YAML.dump(config)) + end + + def create_pipeline + service.execute(:push).payload + end + + def build_tag_list(label:, size: 5) + Array.new(size) { |index| "#{label}-tag-#{index}" } end end |