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/pipeline/chain/seed_spec.rb')
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb159
1 files changed, 141 insertions, 18 deletions
diff --git a/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb
index 80013cab6ee..264076859cb 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb
@@ -3,24 +3,16 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user, developer_projects: [project]) }
- let(:seeds_block) { }
-
- let(:command) do
- Gitlab::Ci::Pipeline::Chain::Command.new(
- project: project,
- current_user: user,
- origin_ref: 'master',
- seeds_block: seeds_block)
- end
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user, developer_projects: [project]) }
+ let(:seeds_block) { }
+ let(:command) { initialize_command }
let(:pipeline) { build(:ci_pipeline, project: project) }
describe '#perform!' do
before do
stub_ci_pipeline_yaml_file(YAML.dump(config))
- run_chain
end
let(:config) do
@@ -28,23 +20,25 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
subject(:run_chain) do
- [
- Gitlab::Ci::Pipeline::Chain::Config::Content.new(pipeline, command),
- Gitlab::Ci::Pipeline::Chain::Config::Process.new(pipeline, command)
- ].map(&:perform!)
-
- described_class.new(pipeline, command).perform!
+ run_previous_chain(pipeline, command)
+ perform_seed(pipeline, command)
end
it 'allocates next IID' do
+ run_chain
+
expect(pipeline.iid).to be_present
end
it 'ensures ci_ref' do
+ run_chain
+
expect(pipeline.ci_ref).to be_present
end
it 'sets the seeds in the command object' do
+ run_chain
+
expect(command.pipeline_seed).to be_a(Gitlab::Ci::Pipeline::Seed::Pipeline)
expect(command.pipeline_seed.size).to eq 1
end
@@ -59,6 +53,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
it 'correctly fabricates stages and builds' do
+ run_chain
+
seed = command.pipeline_seed
expect(seed.stages.size).to eq 2
@@ -84,6 +80,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
it 'returns pipeline seed with jobs only assigned to master' do
+ run_chain
+
seed = command.pipeline_seed
expect(seed.size).to eq 1
@@ -103,6 +101,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
it 'returns pipeline seed with jobs only assigned to schedules' do
+ run_chain
+
seed = command.pipeline_seed
expect(seed.size).to eq 1
@@ -130,6 +130,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
let(:pipeline) { build(:ci_pipeline, project: project) }
it 'returns seeds for kubernetes dependent job' do
+ run_chain
+
seed = command.pipeline_seed
expect(seed.size).to eq 2
@@ -141,6 +143,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
context 'when kubernetes is not active' do
it 'does not return seeds for kubernetes dependent job' do
+ run_chain
+
seed = command.pipeline_seed
expect(seed.size).to eq 1
@@ -158,6 +162,8 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
it 'returns stage seeds only when variables expression is truthy' do
+ run_chain
+
seed = command.pipeline_seed
expect(seed.size).to eq 1
@@ -171,8 +177,125 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
it 'does not execute the block' do
+ run_chain
+
expect(pipeline.variables.size).to eq(0)
end
end
+
+ describe '#root_variables' do
+ let(:config) do
+ {
+ variables: { VAR1: 'var 1' },
+ workflow: {
+ rules: [{ if: '$CI_PIPELINE_SOURCE',
+ variables: { VAR1: 'overridden var 1' } },
+ { when: 'always' }]
+ },
+ rspec: { script: 'rake' }
+ }
+ end
+
+ let(:rspec_variables) { command.pipeline_seed.stages[0].statuses[0].variables.to_hash }
+
+ it 'sends root variable with overridden by rules' do
+ run_chain
+
+ expect(rspec_variables['VAR1']).to eq('overridden var 1')
+ end
+
+ context 'when the FF ci_workflow_rules_variables is disabled' do
+ before do
+ stub_feature_flags(ci_workflow_rules_variables: false)
+ end
+
+ it 'sends root variable' do
+ run_chain
+
+ expect(rspec_variables['VAR1']).to eq('var 1')
+ end
+ end
+ end
+
+ context 'N+1 queries' do
+ it 'avoids N+1 queries when calculating variables of jobs' do
+ pipeline1, command1 = prepare_pipeline1
+ pipeline2, command2 = prepare_pipeline2
+
+ control = ActiveRecord::QueryRecorder.new do
+ perform_seed(pipeline1, command1)
+ end
+
+ expect { perform_seed(pipeline2, command2) }.not_to exceed_query_limit(
+ control.count + expected_extra_queries
+ )
+ end
+
+ private
+
+ def prepare_pipeline1
+ config1 = { build: { stage: 'build', script: 'build' } }
+ stub_ci_pipeline_yaml_file(YAML.dump(config1))
+ pipeline1 = build(:ci_pipeline, project: project)
+ command1 = initialize_command
+
+ run_previous_chain(pipeline1, command1)
+
+ [pipeline1, command1]
+ end
+
+ def prepare_pipeline2
+ config2 = { build1: { stage: 'build', script: 'build1' },
+ build2: { stage: 'build', script: 'build2' },
+ test: { stage: 'build', script: 'test' } }
+ stub_ci_pipeline_yaml_file(YAML.dump(config2))
+ pipeline2 = build(:ci_pipeline, project: project)
+ command2 = initialize_command
+
+ run_previous_chain(pipeline2, command2)
+
+ [pipeline2, command2]
+ end
+
+ def expected_extra_queries
+ extra_jobs = 2
+ non_handled_sql_queries = 3
+
+ # 1. Ci::Build Load () SELECT "ci_builds".* FROM "ci_builds"
+ # WHERE "ci_builds"."type" = 'Ci::Build'
+ # AND "ci_builds"."commit_id" IS NULL
+ # AND ("ci_builds"."retried" = FALSE OR "ci_builds"."retried" IS NULL)
+ # AND (stage_idx < 1)
+ # 2. Ci::InstanceVariable Load => `Ci::InstanceVariable#cached_data` => already cached with `fetch_memory_cache`
+ # 3. Ci::Variable Load => `Project#ci_variables_for` => already cached with `Gitlab::SafeRequestStore`
+
+ extra_jobs * non_handled_sql_queries
+ end
+ end
+
+ private
+
+ def run_previous_chain(pipeline, command)
+ [
+ Gitlab::Ci::Pipeline::Chain::Config::Content.new(pipeline, command),
+ Gitlab::Ci::Pipeline::Chain::Config::Process.new(pipeline, command),
+ Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules.new(pipeline, command)
+ ].map(&:perform!)
+ end
+
+ def perform_seed(pipeline, command)
+ described_class.new(pipeline, command).perform!
+ end
+ end
+
+ private
+
+ def initialize_command
+ Gitlab::Ci::Pipeline::Chain::Command.new(
+ project: project,
+ current_user: user,
+ origin_ref: 'master',
+ seeds_block: seeds_block
+ )
end
end