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:
authorKamil Trzciński <ayufan@ayufan.eu>2018-02-28 22:03:02 +0300
committerKamil Trzciński <ayufan@ayufan.eu>2018-02-28 22:03:02 +0300
commitb1f8d8a1739ff48412c8205f0007a2af8399d097 (patch)
treef7d35d158e7c9bdda6c282f916e02fe9a0d4df90 /spec/services/ci
parent52c3b8f31264230814d2ffa79d0987c1491676b3 (diff)
parent5b08d59f07fc53c1e34819fac20352119d5343e6 (diff)
Merge commit '5b08d59f07fc53c1e34819fac20352119d5343e6' into object-storage-ee-to-ce-backport
Diffstat (limited to 'spec/services/ci')
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb235
-rw-r--r--spec/services/ci/create_trigger_request_service_spec.rb26
-rw-r--r--spec/services/ci/pipeline_trigger_service_spec.rb83
-rw-r--r--spec/services/ci/play_build_service_spec.rb8
-rw-r--r--spec/services/ci/process_pipeline_service_spec.rb35
-rw-r--r--spec/services/ci/register_job_service_spec.rb8
-rw-r--r--spec/services/ci/retry_build_service_spec.rb8
-rw-r--r--spec/services/ci/retry_pipeline_service_spec.rb24
-rw-r--r--spec/services/ci/stop_environments_service_spec.rb2
-rw-r--r--spec/services/ci/update_build_queue_service_spec.rb2
-rw-r--r--spec/services/ci/update_runner_service_spec.rb2
11 files changed, 384 insertions, 49 deletions
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index 77c07b71c68..730df4e0336 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -1,21 +1,28 @@
require 'spec_helper'
-describe Ci::CreatePipelineService, :services do
+describe Ci::CreatePipelineService do
let(:project) { create(:project, :repository) }
let(:user) { create(:admin) }
+ let(:ref_name) { 'refs/heads/master' }
before do
stub_ci_pipeline_to_return_yaml_file
end
describe '#execute' do
- def execute_service(source: :push, after: project.commit.id, message: 'Message', ref: 'refs/heads/master')
+ def execute_service(
+ source: :push,
+ after: project.commit.id,
+ message: 'Message',
+ ref: ref_name,
+ trigger_request: nil)
params = { ref: ref,
before: '00000000',
after: after,
commits: [{ message: message }] }
- described_class.new(project, user, params).execute(source)
+ described_class.new(project, user, params).execute(
+ source, trigger_request: trigger_request)
end
context 'valid params' do
@@ -40,7 +47,7 @@ describe Ci::CreatePipelineService, :services do
it 'increments the prometheus counter' do
expect(Gitlab::Metrics).to receive(:counter)
- .with(:pipelines_created_count, "Pipelines created count")
+ .with(:pipelines_created_total, "Counter of pipelines created")
.and_call_original
pipeline
@@ -68,7 +75,7 @@ describe Ci::CreatePipelineService, :services do
end
context 'when merge request target project is different from source project' do
- let!(:target_project) { create(:project) }
+ let!(:target_project) { create(:project, :repository) }
let!(:forked_project_link) { create(:forked_project_link, forked_to_project: project, forked_from_project: target_project) }
it 'updates head pipeline for merge request' do
@@ -320,5 +327,223 @@ describe Ci::CreatePipelineService, :services do
end.not_to change { Environment.count }
end
end
+
+ context 'when builds with auto-retries are configured' do
+ before do
+ config = YAML.dump(rspec: { script: 'rspec', retry: 2 })
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ it 'correctly creates builds with auto-retry value configured' do
+ pipeline = execute_service
+
+ expect(pipeline).to be_persisted
+ expect(pipeline.builds.find_by(name: 'rspec').retries_max).to eq 2
+ end
+ end
+
+ shared_examples 'when ref is protected' do
+ let(:user) { create(:user) }
+
+ context 'when user is developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'does not create a pipeline' do
+ expect(execute_service).not_to be_persisted
+ expect(Ci::Pipeline.count).to eq(0)
+ end
+ end
+
+ context 'when user is master' do
+ before do
+ project.add_master(user)
+ end
+
+ it 'creates a pipeline' do
+ expect(execute_service).to be_persisted
+ expect(Ci::Pipeline.count).to eq(1)
+ end
+ end
+
+ context 'when trigger belongs to no one' do
+ let(:user) {}
+ let(:trigger_request) { create(:ci_trigger_request) }
+
+ it 'does not create a pipeline' do
+ expect(execute_service(trigger_request: trigger_request))
+ .not_to be_persisted
+ expect(Ci::Pipeline.count).to eq(0)
+ end
+ end
+
+ context 'when trigger belongs to a developer' do
+ let(:user) {}
+
+ let(:trigger_request) do
+ create(:ci_trigger_request).tap do |request|
+ user = create(:user)
+ project.add_developer(user)
+ request.trigger.update(owner: user)
+ end
+ end
+
+ it 'does not create a pipeline' do
+ expect(execute_service(trigger_request: trigger_request))
+ .not_to be_persisted
+ expect(Ci::Pipeline.count).to eq(0)
+ end
+ end
+
+ context 'when trigger belongs to a master' do
+ let(:user) {}
+
+ let(:trigger_request) do
+ create(:ci_trigger_request).tap do |request|
+ user = create(:user)
+ project.add_master(user)
+ request.trigger.update(owner: user)
+ end
+ end
+
+ it 'does not create a pipeline' do
+ expect(execute_service(trigger_request: trigger_request))
+ .to be_persisted
+ expect(Ci::Pipeline.count).to eq(1)
+ end
+ end
+ end
+
+ context 'when ref is a protected branch' do
+ before do
+ create(:protected_branch, project: project, name: 'master')
+ end
+
+ it_behaves_like 'when ref is protected'
+ end
+
+ context 'when ref is a protected tag' do
+ let(:ref_name) { 'refs/tags/v1.0.0' }
+
+ before do
+ create(:protected_tag, project: project, name: '*')
+ end
+
+ it_behaves_like 'when ref is protected'
+ end
+
+ context 'when ref is not protected' do
+ context 'when trigger belongs to no one' do
+ let(:user) {}
+ let(:trigger_request) { create(:ci_trigger_request) }
+
+ it 'creates a pipeline' do
+ expect(execute_service(trigger_request: trigger_request))
+ .to be_persisted
+ expect(Ci::Pipeline.count).to eq(1)
+ end
+ end
+ end
+ end
+
+ describe '#allowed_to_create?' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:ref) { 'master' }
+
+ subject do
+ described_class.new(project, user, ref: ref)
+ .send(:allowed_to_create?, user)
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it { is_expected.to be_truthy }
+
+ context 'when the branch is protected' do
+ let!(:protected_branch) do
+ create(:protected_branch, project: project, name: ref)
+ end
+
+ it { is_expected.to be_falsey }
+
+ context 'when developers are allowed to merge' do
+ let!(:protected_branch) do
+ create(:protected_branch,
+ :developers_can_merge,
+ project: project,
+ name: ref)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
+ context 'when the tag is protected' do
+ let(:ref) { 'v1.0.0' }
+
+ let!(:protected_tag) do
+ create(:protected_tag, project: project, name: ref)
+ end
+
+ it { is_expected.to be_falsey }
+
+ context 'when developers are allowed to create the tag' do
+ let!(:protected_tag) do
+ create(:protected_tag,
+ :developers_can_create,
+ project: project,
+ name: ref)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+ end
+
+ context 'when user is a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it { is_expected.to be_truthy }
+
+ context 'when the branch is protected' do
+ let!(:protected_branch) do
+ create(:protected_branch, project: project, name: ref)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when the tag is protected' do
+ let(:ref) { 'v1.0.0' }
+
+ let!(:protected_tag) do
+ create(:protected_tag, project: project, name: ref)
+ end
+
+ it { is_expected.to be_truthy }
+
+ context 'when no one can create the tag' do
+ let!(:protected_tag) do
+ create(:protected_tag,
+ :no_one_can_create,
+ project: project,
+ name: ref)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+ end
+
+ context 'when owner cannot create pipeline' do
+ it { is_expected.to be_falsey }
+ end
end
end
diff --git a/spec/services/ci/create_trigger_request_service_spec.rb b/spec/services/ci/create_trigger_request_service_spec.rb
index f2956262f4b..8295813a1ca 100644
--- a/spec/services/ci/create_trigger_request_service_spec.rb
+++ b/spec/services/ci/create_trigger_request_service_spec.rb
@@ -1,12 +1,15 @@
require 'spec_helper'
-describe Ci::CreateTriggerRequestService, services: true do
- let(:service) { described_class.new }
+describe Ci::CreateTriggerRequestService do
+ let(:service) { described_class }
let(:project) { create(:project, :repository) }
- let(:trigger) { create(:ci_trigger, project: project) }
+ let(:trigger) { create(:ci_trigger, project: project, owner: owner) }
+ let(:owner) { create(:user) }
before do
stub_ci_pipeline_to_return_yaml_file
+
+ project.add_developer(owner)
end
describe '#execute' do
@@ -14,29 +17,26 @@ describe Ci::CreateTriggerRequestService, services: true do
subject { service.execute(project, trigger, 'master') }
context 'without owner' do
- it { expect(subject).to be_kind_of(Ci::TriggerRequest) }
+ it { expect(subject.trigger_request).to be_kind_of(Ci::TriggerRequest) }
+ it { expect(subject.trigger_request.builds.first).to be_kind_of(Ci::Build) }
it { expect(subject.pipeline).to be_kind_of(Ci::Pipeline) }
it { expect(subject.pipeline).to be_trigger }
- it { expect(subject.builds.first).to be_kind_of(Ci::Build) }
end
context 'with owner' do
- let(:owner) { create(:user) }
- let(:trigger) { create(:ci_trigger, project: project, owner: owner) }
-
- it { expect(subject).to be_kind_of(Ci::TriggerRequest) }
+ it { expect(subject.trigger_request).to be_kind_of(Ci::TriggerRequest) }
+ it { expect(subject.trigger_request.builds.first).to be_kind_of(Ci::Build) }
+ it { expect(subject.trigger_request.builds.first.user).to eq(owner) }
it { expect(subject.pipeline).to be_kind_of(Ci::Pipeline) }
it { expect(subject.pipeline).to be_trigger }
it { expect(subject.pipeline.user).to eq(owner) }
- it { expect(subject.builds.first).to be_kind_of(Ci::Build) }
- it { expect(subject.builds.first.user).to eq(owner) }
end
end
context 'no commit for ref' do
subject { service.execute(project, trigger, 'other-branch') }
- it { expect(subject).to be_nil }
+ it { expect(subject.pipeline).not_to be_persisted }
end
context 'no builds created' do
@@ -46,7 +46,7 @@ describe Ci::CreateTriggerRequestService, services: true do
stub_ci_pipeline_yaml_file('script: { only: [develop], script: hello World }')
end
- it { expect(subject).to be_nil }
+ it { expect(subject.pipeline).not_to be_persisted }
end
end
end
diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb
new file mode 100644
index 00000000000..9a6875e448c
--- /dev/null
+++ b/spec/services/ci/pipeline_trigger_service_spec.rb
@@ -0,0 +1,83 @@
+require 'spec_helper'
+
+describe Ci::PipelineTriggerService do
+ let(:project) { create(:project, :repository) }
+
+ before do
+ stub_ci_pipeline_to_return_yaml_file
+ end
+
+ describe '#execute' do
+ let(:user) { create(:user) }
+ let(:trigger) { create(:ci_trigger, project: project, owner: user) }
+ let(:result) { described_class.new(project, user, params).execute }
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when trigger belongs to a different project' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
+ let(:trigger) { create(:ci_trigger, project: create(:project), owner: user) }
+
+ it 'does nothing' do
+ expect { result }.not_to change { Ci::Pipeline.count }
+ end
+ end
+
+ context 'when params have an existsed trigger token' do
+ context 'when params have an existsed ref' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
+
+ it 'triggers a pipeline' do
+ expect { result }.to change { Ci::Pipeline.count }.by(1)
+ expect(result[:pipeline].ref).to eq('master')
+ expect(result[:pipeline].project).to eq(project)
+ expect(result[:pipeline].user).to eq(trigger.owner)
+ expect(result[:status]).to eq(:success)
+ end
+
+ context 'when commit message has [ci skip]' do
+ before do
+ allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' }
+ end
+
+ it 'ignores [ci skip] and create as general' do
+ expect { result }.to change { Ci::Pipeline.count }.by(1)
+ expect(result[:status]).to eq(:success)
+ end
+ end
+
+ context 'when params have a variable' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: variables } }
+ let(:variables) { { 'AAA' => 'AAA123' } }
+
+ it 'has a variable' do
+ expect { result }.to change { Ci::PipelineVariable.count }.by(1)
+ .and change { Ci::TriggerRequest.count }.by(1)
+ expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables)
+ expect(result[:pipeline].trigger_requests.last.variables).to be_nil
+ end
+ end
+ end
+
+ context 'when params have a non-existsed ref' do
+ let(:params) { { token: trigger.token, ref: 'invalid-ref', variables: nil } }
+
+ it 'does not trigger a pipeline' do
+ expect { result }.not_to change { Ci::Pipeline.count }
+ expect(result[:http_status]).to eq(400)
+ end
+ end
+ end
+
+ context 'when params have a non-existsed trigger token' do
+ let(:params) { { token: 'invalid-token', ref: nil, variables: nil } }
+
+ it 'does not trigger a pipeline' do
+ expect { result }.not_to change { Ci::Pipeline.count }
+ expect(result).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/play_build_service_spec.rb b/spec/services/ci/play_build_service_spec.rb
index ea211de1f82..330ec81e87d 100644
--- a/spec/services/ci/play_build_service_spec.rb
+++ b/spec/services/ci/play_build_service_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-describe Ci::PlayBuildService, '#execute', :services do
+describe Ci::PlayBuildService, '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, :manual, pipeline: pipeline) }
@@ -11,7 +11,7 @@ describe Ci::PlayBuildService, '#execute', :services do
end
context 'when project does not have repository yet' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'allows user to play build if protected branch rules are met' do
project.add_developer(user)
@@ -33,7 +33,7 @@ describe Ci::PlayBuildService, '#execute', :services do
end
context 'when project has repository' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
it 'allows user with developer role to play a build' do
project.add_developer(user)
diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb
index efcaccc254e..214adc9960f 100644
--- a/spec/services/ci/process_pipeline_service_spec.rb
+++ b/spec/services/ci/process_pipeline_service_spec.rb
@@ -1,14 +1,16 @@
require 'spec_helper'
-describe Ci::ProcessPipelineService, '#execute', :services do
+describe Ci::ProcessPipelineService, '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_empty_pipeline, ref: 'master', project: project)
end
before do
+ stub_not_protect_default_branch
+
project.add_developer(user)
end
@@ -463,6 +465,35 @@ describe Ci::ProcessPipelineService, '#execute', :services do
end
end
+ context 'when builds with auto-retries are configured' do
+ before do
+ create_build('build:1', stage_idx: 0, user: user, options: { retry: 2 })
+ create_build('test:1', stage_idx: 1, user: user, when: :on_failure)
+ create_build('test:2', stage_idx: 1, user: user, options: { retry: 1 })
+ end
+
+ it 'automatically retries builds in a valid order' do
+ expect(process_pipeline).to be_truthy
+
+ fail_running_or_pending
+
+ expect(builds_names).to eq %w[build:1 build:1]
+ expect(builds_statuses).to eq %w[failed pending]
+
+ succeed_running_or_pending
+
+ expect(builds_names).to eq %w[build:1 build:1 test:2]
+ expect(builds_statuses).to eq %w[failed success pending]
+
+ succeed_running_or_pending
+
+ expect(builds_names).to eq %w[build:1 build:1 test:2]
+ expect(builds_statuses).to eq %w[failed success success]
+
+ expect(pipeline.reload).to be_success
+ end
+ end
+
def process_pipeline
described_class.new(pipeline.project, user).execute(pipeline)
end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 62ba0b01339..8eb0d2d10a4 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
module Ci
- describe RegisterJobService, services: true do
- let!(:project) { FactoryGirl.create :empty_project, shared_runners_enabled: false }
+ describe RegisterJobService do
+ let!(:project) { FactoryGirl.create :project, shared_runners_enabled: false }
let!(:pipeline) { FactoryGirl.create :ci_pipeline, project: project }
let!(:pending_build) { FactoryGirl.create :ci_build, pipeline: pipeline }
let!(:shared_runner) { FactoryGirl.create(:ci_runner, is_shared: true) }
@@ -72,9 +72,9 @@ module Ci
end
context 'for multiple builds' do
- let!(:project2) { create :empty_project, shared_runners_enabled: true }
+ let!(:project2) { create :project, shared_runners_enabled: true }
let!(:pipeline2) { create :ci_pipeline, project: project2 }
- let!(:project3) { create :empty_project, shared_runners_enabled: true }
+ let!(:project3) { create :project, shared_runners_enabled: true }
let!(:pipeline3) { create :ci_pipeline, project: project3 }
let!(:build1_project1) { pending_build }
let!(:build2_project1) { FactoryGirl.create :ci_build, pipeline: pipeline }
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index 365ecad3a39..81599875f5b 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-describe Ci::RetryBuildService, :services do
+describe Ci::RetryBuildService do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline) }
@@ -86,6 +86,8 @@ describe Ci::RetryBuildService, :services do
context 'when user has ability to execute build' do
before do
+ stub_not_protect_default_branch
+
project.add_developer(user)
end
@@ -132,6 +134,8 @@ describe Ci::RetryBuildService, :services do
context 'when user has ability to execute build' do
before do
+ stub_not_protect_default_branch
+
project.add_developer(user)
end
diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb
index 3e860203063..6ce75c65c8c 100644
--- a/spec/services/ci/retry_pipeline_service_spec.rb
+++ b/spec/services/ci/retry_pipeline_service_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-describe Ci::RetryPipelineService, '#execute', :services do
+describe Ci::RetryPipelineService, '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:service) { described_class.new(project, user) }
@@ -244,13 +244,9 @@ describe Ci::RetryPipelineService, '#execute', :services do
create_build('verify', :canceled, 1)
end
- it 'does not reprocess manual action' do
- service.execute(pipeline)
-
- expect(build('test')).to be_pending
- expect(build('deploy')).to be_failed
- expect(build('verify')).to be_created
- expect(pipeline.reload).to be_running
+ it 'raises an error' do
+ expect { service.execute(pipeline) }
+ .to raise_error Gitlab::Access::AccessDeniedError
end
end
@@ -261,13 +257,9 @@ describe Ci::RetryPipelineService, '#execute', :services do
create_build('verify', :canceled, 2)
end
- it 'does not reprocess manual action' do
- service.execute(pipeline)
-
- expect(build('test')).to be_pending
- expect(build('deploy')).to be_failed
- expect(build('verify')).to be_created
- expect(pipeline.reload).to be_running
+ it 'raises an error' do
+ expect { service.execute(pipeline) }
+ .to raise_error Gitlab::Access::AccessDeniedError
end
end
end
diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb
index 98044ad232e..e2a9ed27e87 100644
--- a/spec/services/ci/stop_environments_service_spec.rb
+++ b/spec/services/ci/stop_environments_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Ci::StopEnvironmentsService, services: true do
+describe Ci::StopEnvironmentsService do
let(:project) { create(:project, :private, :repository) }
let(:user) { create(:user) }
diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb
index efefa8e8eca..0da0e57dbcd 100644
--- a/spec/services/ci/update_build_queue_service_spec.rb
+++ b/spec/services/ci/update_build_queue_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Ci::UpdateBuildQueueService, :services do
+describe Ci::UpdateBuildQueueService do
let(:project) { create(:project, :repository) }
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/update_runner_service_spec.rb b/spec/services/ci/update_runner_service_spec.rb
index e429fcfc72f..7cc04c92d27 100644
--- a/spec/services/ci/update_runner_service_spec.rb
+++ b/spec/services/ci/update_runner_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Ci::UpdateRunnerService, :services do
+describe Ci::UpdateRunnerService do
let(:runner) { create(:ci_runner) }
describe '#update' do