gitlab-ce/spec/services/ci/create_pipeline_service/inputs_spec.rb

221 lines
6.7 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::CreatePipelineService, feature_category: :pipeline_composition do
include RepoHelpers
context 'for inputs' do
let_it_be(:project) { create(:project, :small_repo) }
let_it_be(:user) { project.first_owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
let(:content) { nil }
let(:inputs) { {} }
let_it_be(:complex_inputs_example_path) { 'spec/lib/gitlab/ci/config/yaml/fixtures/complex-included-ci.yml' }
let_it_be(:complex_inputs_example_yaml) { File.read(Rails.root.join(complex_inputs_example_path)) }
let(:project_ci_config_path) { nil } # default: .gitlab-ci.yml
let(:service) { described_class.new(project, user, { ref: ref }) }
subject(:execute) { service.execute(source, content: content, inputs: inputs) }
before do
project.ci_config_path = project_ci_config_path
end
shared_examples 'returning errors' do
it 'returns errors' do
response = execute
pipeline = response.payload
expect(response).to be_error
errors = pipeline.error_messages.map(&:content)
expect(errors.size).to eq(1)
expected_errors.each do |error|
expect(errors.first).to include(error)
end
end
end
shared_examples 'testing invalid and valid cases' do
context 'when passing no inputs' do
let(:expected_errors) do
[
'`deploy_strategy` input: required value has not been provided',
'`job_stage` input: required value has not been provided',
'`test_script` input: required value has not been provided'
]
end
it_behaves_like 'returning errors'
end
context 'when passing invalid inputs' do
let(:inputs) do
{
deploy_strategy: 'manual',
job_stage: 'deploy',
test_script: 'echo "test"'
}
end
let(:expected_errors) do
[
'`deploy_strategy` input: `manual` cannot be used because it is not in the list of allowed options',
'`test_script` input: provided value is not an array'
]
end
it_behaves_like 'returning errors'
end
context 'when passing valid inputs' do
let(:inputs) do
{
deploy_strategy: 'blue-green',
job_stage: 'deploy',
test_script: ['echo "test"'],
test_rules: [
{ if: '$CI_PIPELINE_SOURCE == "push"' }
],
test_framework: '$TEST_FRAMEWORK'
}
end
before_all do
create(:ci_variable, project: project, key: 'TEST_FRAMEWORK', value: 'rspec')
end
it 'creates a pipeline with correct jobs' do
response = execute
pipeline = response.payload
expect(response).to be_success
expect(pipeline).to be_created_successfully
expect(pipeline.builds.map(&:name)).to contain_exactly(
'my-job-build 1/2', 'my-job-build 2/2', 'my-job-test', 'my-job-test-2', 'my-job-deploy'
)
expect(pipeline.builds.map(&:stage)).to contain_exactly('deploy', 'deploy', 'deploy', 'deploy', 'deploy')
my_job_test = pipeline.builds.find { |build| build.name == 'my-job-test' }
expect(my_job_test.options[:script]).to eq([
'echo "Testing with rspec"',
'if [ false == true ]; then echo "Coverage is enabled"; fi'
])
my_job_test_2 = pipeline.builds.find { |build| build.name == 'my-job-test-2' }
expect(my_job_test_2.options[:script]).to eq(['echo "test"'])
my_job_deploy = pipeline.builds.find { |build| build.name == 'my-job-deploy' }
expect(my_job_deploy.options[:script]).to eq(['echo "Deploying to staging using blue-green strategy"'])
end
context 'when the FF ci_inputs_for_pipelines is disabled' do
before do
stub_feature_flags(ci_inputs_for_pipelines: false)
end
let(:expected_errors) do
[
'`deploy_strategy` input: required value has not been provided',
'`job_stage` input: required value has not been provided',
'`test_script` input: required value has not been provided'
]
end
it_behaves_like 'returning errors'
end
end
end
context 'when the project CI config is in the current repository file' do
let(:project_files) do
{ '.gitlab-ci.yml' => complex_inputs_example_yaml }
end
around do |example|
create_and_delete_files(project, project_files) do
example.run
end
end
it_behaves_like 'testing invalid and valid cases'
end
context 'when the project CI config is in another project repository file' do
let_it_be(:project_2) do
create(:project, :custom_repo, files: { 'a_config_file.yml' => complex_inputs_example_yaml })
end
let(:project_ci_config_path) { "a_config_file.yml@#{project_2.full_path}:#{project_2.default_branch}" }
before_all do
project_2.add_developer(user)
end
it_behaves_like 'testing invalid and valid cases'
end
context 'when the project CI config is a remote file' do
let(:project_ci_config_path) { 'https://gitlab.example.com/something/.gitlab-ci.yml' }
before do
stub_request(:get, project_ci_config_path)
.to_return(status: 200, body: complex_inputs_example_yaml)
end
it_behaves_like 'testing invalid and valid cases'
end
context 'when the CI config is passed as content' do
let(:content) { complex_inputs_example_yaml }
it_behaves_like 'testing invalid and valid cases'
end
context 'when the CI config does not have spec:inputs' do
let(:content) do
<<~YAML
job:
script: echo "hello"
YAML
end
context 'when passing inputs' do
let(:inputs) do
{ deploy_strategy: 'blue-green' }
end
let(:expected_errors) do
['Given inputs not defined in the `spec` section of the included configuration file']
end
it_behaves_like 'returning errors'
context 'when the FF ci_inputs_for_pipelines is disabled' do
before do
stub_feature_flags(ci_inputs_for_pipelines: false)
end
it 'creates a pipeline' do
response = execute
pipeline = response.payload
expect(response).to be_success
expect(pipeline).to be_created_successfully
expect(pipeline.builds.map(&:name)).to contain_exactly('job')
end
end
end
end
end
end