diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2016-11-25 12:48:04 +0300 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2016-11-25 12:48:04 +0300 |
commit | afe90d529c82566886d1f2513dd6bee4fa73ff94 (patch) | |
tree | abce0a1bd9403f9157fbad2875159220ac1a213e /spec/models/ci | |
parent | 90a3b3ab5680d6b62de0aa446da52e01d378f81e (diff) | |
parent | bd3a544ab0417b758cf5e8e5bcd4ae9c0fed1bae (diff) |
Merge branch 'fix-cancelling-pipelines' into 'master'
Improve how we could cancel pipelines:
Improve how we could cancel pipelines:
* Introduce `HasStatus.cancelable` which we might be able to cancel
* Cancel and check upon `cancelable`
* Also cancel on `CommitStatus` rather than just `Ci::Build`
Fixes #23635
Fixes #17845
See merge request !7508
Diffstat (limited to 'spec/models/ci')
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index ea022e03608..3b12f16b4db 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -402,6 +402,160 @@ describe Ci::Pipeline, models: true do end end + describe '#cancelable?' do + %i[created running pending].each do |status0| + context "when there is a build #{status0}" do + before do + create(:ci_build, status0, pipeline: pipeline) + end + + it 'is cancelable' do + expect(pipeline.cancelable?).to be_truthy + end + end + + context "when there is an external job #{status0}" do + before do + create(:generic_commit_status, status0, pipeline: pipeline) + end + + it 'is cancelable' do + expect(pipeline.cancelable?).to be_truthy + end + end + + %i[success failed canceled].each do |status1| + context "when there are generic_commit_status jobs for #{status0} and #{status1}" do + before do + create(:generic_commit_status, status0, pipeline: pipeline) + create(:generic_commit_status, status1, pipeline: pipeline) + end + + it 'is cancelable' do + expect(pipeline.cancelable?).to be_truthy + end + end + + context "when there are generic_commit_status and ci_build jobs for #{status0} and #{status1}" do + before do + create(:generic_commit_status, status0, pipeline: pipeline) + create(:ci_build, status1, pipeline: pipeline) + end + + it 'is cancelable' do + expect(pipeline.cancelable?).to be_truthy + end + end + + context "when there are ci_build jobs for #{status0} and #{status1}" do + before do + create(:ci_build, status0, pipeline: pipeline) + create(:ci_build, status1, pipeline: pipeline) + end + + it 'is cancelable' do + expect(pipeline.cancelable?).to be_truthy + end + end + end + end + + %i[success failed canceled].each do |status| + context "when there is a build #{status}" do + before do + create(:ci_build, status, pipeline: pipeline) + end + + it 'is not cancelable' do + expect(pipeline.cancelable?).to be_falsey + end + end + + context "when there is an external job #{status}" do + before do + create(:generic_commit_status, status, pipeline: pipeline) + end + + it 'is not cancelable' do + expect(pipeline.cancelable?).to be_falsey + end + end + end + end + + describe '#cancel_running' do + let(:latest_status) { pipeline.statuses.pluck(:status) } + + context 'when there is a running external job and created build' do + before do + create(:ci_build, :running, pipeline: pipeline) + create(:generic_commit_status, :running, pipeline: pipeline) + + pipeline.cancel_running + end + + it 'cancels both jobs' do + expect(latest_status).to contain_exactly('canceled', 'canceled') + end + end + + context 'when builds are in different stages' do + before do + create(:ci_build, :running, stage_idx: 0, pipeline: pipeline) + create(:ci_build, :running, stage_idx: 1, pipeline: pipeline) + + pipeline.cancel_running + end + + it 'cancels both jobs' do + expect(latest_status).to contain_exactly('canceled', 'canceled') + end + end + end + + describe '#retry_failed' do + let(:latest_status) { pipeline.statuses.latest.pluck(:status) } + + context 'when there is a failed build and failed external status' do + before do + create(:ci_build, :failed, name: 'build', pipeline: pipeline) + create(:generic_commit_status, :failed, name: 'jenkins', pipeline: pipeline) + + pipeline.retry_failed(create(:user)) + end + + it 'retries only build' do + expect(latest_status).to contain_exactly('pending', 'failed') + end + end + + context 'when builds are in different stages' do + before do + create(:ci_build, :failed, name: 'build', stage_idx: 0, pipeline: pipeline) + create(:ci_build, :failed, name: 'jenkins', stage_idx: 1, pipeline: pipeline) + + pipeline.retry_failed(create(:user)) + end + + it 'retries both builds' do + expect(latest_status).to contain_exactly('pending', 'pending') + end + end + + context 'when there are canceled and failed' do + before do + create(:ci_build, :failed, name: 'build', stage_idx: 0, pipeline: pipeline) + create(:ci_build, :canceled, name: 'jenkins', stage_idx: 1, pipeline: pipeline) + + pipeline.retry_failed(create(:user)) + end + + it 'retries both builds' do + expect(latest_status).to contain_exactly('pending', 'pending') + end + end + end + describe '#execute_hooks' do let!(:build_a) { create_build('a', 0) } let!(:build_b) { create_build('b', 1) } |