Commit 4dc61dc7 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'all-skipped-equals-success' into 'master'

Skipped jobs should be considered successful

## What does this MR do?

If all jobs in previous stage are all skipped, the next stage should consider previous stage succeeded.

## Why was this MR needed?

Since for now we consider all manual jobs if skipped, should not block the next stage from running.

Closes #22598 

See also #20342 (because this merge request conflicts with it)

See merge request !6604
parents 1b7dda70 22aaebdf
...@@ -23,6 +23,7 @@ v 8.13.0 (unreleased) ...@@ -23,6 +23,7 @@ v 8.13.0 (unreleased)
- Fix todos page mobile viewport layout (ClemMakesApps) - Fix todos page mobile viewport layout (ClemMakesApps)
- Fix robots.txt disallowing access to groups starting with "s" (Matt Harrison) - Fix robots.txt disallowing access to groups starting with "s" (Matt Harrison)
- Close open merge request without source project (Katarzyna Kobierska Ula Budziszewska) - Close open merge request without source project (Katarzyna Kobierska Ula Budziszewska)
- Fix that manual jobs would no longer block jobs in the next stage. !6604
- Add configurable email subject suffix (Fu Xu) - Add configurable email subject suffix (Fu Xu)
- Use a ConnectionPool for Rails.cache on Sidekiq servers - Use a ConnectionPool for Rails.cache on Sidekiq servers
- Replace `alias_method_chain` with `Module#prepend` - Replace `alias_method_chain` with `Module#prepend`
......
...@@ -196,7 +196,7 @@ module Ci ...@@ -196,7 +196,7 @@ module Ci
end end
def has_warnings? def has_warnings?
builds.latest.ignored.any? builds.latest.failed_but_allowed.any?
end end
def config_processor def config_processor
......
...@@ -24,7 +24,22 @@ class CommitStatus < ActiveRecord::Base ...@@ -24,7 +24,22 @@ class CommitStatus < ActiveRecord::Base
scope :retried, -> { where.not(id: latest) } scope :retried, -> { where.not(id: latest) }
scope :ordered, -> { order(:name) } scope :ordered, -> { order(:name) }
scope :ignored, -> { where(allow_failure: true, status: [:failed, :canceled]) }
scope :failed_but_allowed, -> do
where(allow_failure: true, status: [:failed, :canceled])
end
scope :exclude_ignored, -> do
quoted_when = connection.quote_column_name('when')
# We want to ignore failed_but_allowed jobs
where("allow_failure = ? OR status IN (?)",
false, all_state_names - [:failed, :canceled]).
# We want to ignore skipped manual jobs
where("#{quoted_when} <> ? OR status <> ?", 'manual', 'skipped').
# We want to ignore skipped on_failure
where("#{quoted_when} <> ? OR status <> ?", 'on_failure', 'skipped')
end
scope :latest_ci_stages, -> { latest.ordered.includes(project: :namespace) } scope :latest_ci_stages, -> { latest.ordered.includes(project: :namespace) }
scope :retried_ci_stages, -> { retried.ordered.includes(project: :namespace) } scope :retried_ci_stages, -> { retried.ordered.includes(project: :namespace) }
...@@ -111,7 +126,7 @@ class CommitStatus < ActiveRecord::Base ...@@ -111,7 +126,7 @@ class CommitStatus < ActiveRecord::Base
end end
end end
def ignored? def failed_but_allowed?
allow_failure? && (failed? || canceled?) allow_failure? && (failed? || canceled?)
end end
......
...@@ -8,32 +8,32 @@ module HasStatus ...@@ -8,32 +8,32 @@ module HasStatus
class_methods do class_methods do
def status_sql def status_sql
scope = all scope = if respond_to?(:exclude_ignored)
exclude_ignored
else
all
end
builds = scope.select('count(*)').to_sql builds = scope.select('count(*)').to_sql
created = scope.created.select('count(*)').to_sql created = scope.created.select('count(*)').to_sql
success = scope.success.select('count(*)').to_sql success = scope.success.select('count(*)').to_sql
ignored = scope.ignored.select('count(*)').to_sql if scope.respond_to?(:ignored)
ignored ||= '0'
pending = scope.pending.select('count(*)').to_sql pending = scope.pending.select('count(*)').to_sql
running = scope.running.select('count(*)').to_sql running = scope.running.select('count(*)').to_sql
canceled = scope.canceled.select('count(*)').to_sql
skipped = scope.skipped.select('count(*)').to_sql skipped = scope.skipped.select('count(*)').to_sql
canceled = scope.canceled.select('count(*)').to_sql
deduce_status = "(CASE "(CASE
WHEN (#{builds})=(#{success}) THEN 'success'
WHEN (#{builds})=(#{created}) THEN 'created' WHEN (#{builds})=(#{created}) THEN 'created'
WHEN (#{builds})=(#{skipped}) THEN 'skipped' WHEN (#{builds})=(#{success})+(#{skipped}) THEN 'skipped'
WHEN (#{builds})=(#{success})+(#{ignored})+(#{skipped}) THEN 'success' WHEN (#{builds})=(#{success})+(#{skipped})+(#{canceled}) THEN 'canceled'
WHEN (#{builds})=(#{created})+(#{pending})+(#{skipped}) THEN 'pending' WHEN (#{builds})=(#{created})+(#{skipped})+(#{pending}) THEN 'pending'
WHEN (#{builds})=(#{canceled})+(#{success})+(#{ignored})+(#{skipped}) THEN 'canceled'
WHEN (#{running})+(#{pending})+(#{created})>0 THEN 'running' WHEN (#{running})+(#{pending})+(#{created})>0 THEN 'running'
ELSE 'failed' ELSE 'failed'
END)" END)"
deduce_status
end end
def status def status
all.pluck(self.status_sql).first all.pluck(status_sql).first
end end
def started_at def started_at
...@@ -43,6 +43,10 @@ module HasStatus ...@@ -43,6 +43,10 @@ module HasStatus
def finished_at def finished_at
all.maximum(:finished_at) all.maximum(:finished_at)
end end
def all_state_names
state_machines.values.flat_map(&:states).flat_map { |s| s.map(&:name) }
end
end end
included do included do
......
...@@ -39,8 +39,8 @@ describe Ci::Build, models: true do ...@@ -39,8 +39,8 @@ describe Ci::Build, models: true do
end end
end end
describe '#ignored?' do describe '#failed_but_allowed?' do
subject { build.ignored? } subject { build.failed_but_allowed? }
context 'when build is not allowed to fail' do context 'when build is not allowed to fail' do
before do before do
......
...@@ -7,7 +7,11 @@ describe CommitStatus, models: true do ...@@ -7,7 +7,11 @@ describe CommitStatus, models: true do
create(:ci_pipeline, project: project, sha: project.commit.id) create(:ci_pipeline, project: project, sha: project.commit.id)
end end
let(:commit_status) { create(:commit_status, pipeline: pipeline) } let(:commit_status) { create_status }
def create_status(args = {})
create(:commit_status, args.merge(pipeline: pipeline))
end
it { is_expected.to belong_to(:pipeline) } it { is_expected.to belong_to(:pipeline) }
it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:user) }
...@@ -125,32 +129,53 @@ describe CommitStatus, models: true do ...@@ -125,32 +129,53 @@ describe CommitStatus, models: true do
describe '.latest' do describe '.latest' do
subject { CommitStatus.latest.order(:id) } subject { CommitStatus.latest.order(:id) }
before do let(:statuses) do
@commit1 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'bb', status: 'running' [create_status(name: 'aa', ref: 'bb', status: 'running'),
@commit2 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'cc', ref: 'cc', status: 'pending' create_status(name: 'cc', ref: 'cc', status: 'pending'),
@commit3 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'cc', status: 'success' create_status(name: 'aa', ref: 'cc', status: 'success'),
@commit4 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'cc', ref: 'bb', status: 'success' create_status(name: 'cc', ref: 'bb', status: 'success'),
@commit5 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'bb', status: 'success' create_status(name: 'aa', ref: 'bb', status: 'success')]
end end
it 'returns unique statuses' do it 'returns unique statuses' do
is_expected.to eq([@commit4, @commit5]) is_expected.to eq(statuses.values_at(3, 4))
end end
end end
describe '.running_or_pending' do describe '.running_or_pending' do
subject { CommitStatus.running_or_pending.order(:id) } subject { CommitStatus.running_or_pending.order(:id) }
before do let(:statuses) do
@commit1 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'bb', status: 'running' [create_status(name: 'aa', ref: 'bb', status: 'running'),
@commit2 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'cc', ref: 'cc', status: 'pending' create_status(name: 'cc', ref: 'cc', status: 'pending'),
@commit3 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: nil, status: 'success' create_status(name: 'aa', ref: nil, status: 'success'),
@commit4 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'dd', ref: nil, status: 'failed' create_status(name: 'dd', ref: nil, status: 'failed'),
@commit5 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'ee', ref: nil, status: 'canceled' create_status(name: 'ee', ref: nil, status: 'canceled')]
end end
it 'returns statuses that are running or pending' do it 'returns statuses that are running or pending' do
is_expected.to eq([@commit1, @commit2]) is_expected.to eq(statuses.values_at(0, 1))
end
end
describe '.exclude_ignored' do
subject { CommitStatus.exclude_ignored.order(:id) }
let(:statuses) do
[create_status(when: 'manual', status: 'skipped'),
create_status(when: 'manual', status: 'success'),
create_status(when: 'manual', status: 'failed'),
create_status(when: 'on_failure', status: 'skipped'),
create_status(when: 'on_failure', status: 'success'),
create_status(when: 'on_failure', status: 'failed'),
create_status(allow_failure: true, status: 'success'),
create_status(allow_failure: true, status: 'failed'),
create_status(allow_failure: false, status: 'success'),
create_status(allow_failure: false, status: 'failed')]
end
it 'returns statuses without what we want to ignore' do
is_expected.to eq(statuses.values_at(1, 2, 4, 5, 6, 8, 9))
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe HasStatus do describe HasStatus do
before do
@object = Object.new
@object.extend(HasStatus::ClassMethods)
end
describe '.status' do describe '.status' do
before do subject { CommitStatus.status }
allow(@object).to receive(:all).and_return(CommitStatus.where(id: statuses))
end
subject { @object.status }
shared_examples 'build status summary' do shared_examples 'build status summary' do
context 'all successful' do context 'all successful' do
let(:statuses) { Array.new(2) { create(type, status: :success) } } let!(:statuses) { Array.new(2) { create(type, status: :success) } }
it { is_expected.to eq 'success' } it { is_expected.to eq 'success' }
end end
context 'at least one failed' do context 'at least one failed' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), create(type, status: :failed)] [create(type, status: :success), create(type, status: :failed)]
end end
...@@ -28,7 +19,7 @@ describe HasStatus do ...@@ -28,7 +19,7 @@ describe HasStatus do
end end
context 'at least one running' do context 'at least one running' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), create(type, status: :running)] [create(type, status: :success), create(type, status: :running)]
end end
...@@ -36,7 +27,7 @@ describe HasStatus do ...@@ -36,7 +27,7 @@ describe HasStatus do
end end
context 'at least one pending' do context 'at least one pending' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), create(type, status: :pending)] [create(type, status: :success), create(type, status: :pending)]
end end
...@@ -44,7 +35,7 @@ describe HasStatus do ...@@ -44,7 +35,7 @@ describe HasStatus do
end end
context 'success and failed but allowed to fail' do context 'success and failed but allowed to fail' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), [create(type, status: :success),
create(type, status: :failed, allow_failure: true)] create(type, status: :failed, allow_failure: true)]
end end
...@@ -53,12 +44,15 @@ describe HasStatus do ...@@ -53,12 +44,15 @@ describe HasStatus do
end end
context 'one failed but allowed to fail' do context 'one failed but allowed to fail' do
let(:statuses) { [create(type, status: :failed, allow_failure: true)] } let!(:statuses) do
[create(type, status: :failed, allow_failure: true)]
end
it { is_expected.to eq 'success' } it { is_expected.to eq 'success' }
end end
context 'success and canceled' do context 'success and canceled' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), create(type, status: :canceled)] [create(type, status: :success), create(type, status: :canceled)]
end end
...@@ -66,7 +60,7 @@ describe HasStatus do ...@@ -66,7 +60,7 @@ describe HasStatus do
end end
context 'one failed and one canceled' do context 'one failed and one canceled' do
let(:statuses) do let!(:statuses) do
[create(type, status: :failed), create(type, status: :canceled)] [create(type, status: :failed), create(type, status: :canceled)]
end end
...@@ -74,7 +68,7 @@ describe HasStatus do ...@@ -74,7 +68,7 @@ describe HasStatus do
end end
context 'one failed but allowed to fail and one canceled' do context 'one failed but allowed to fail and one canceled' do
let(:statuses) do let!(:statuses) do
[create(type, status: :failed, allow_failure: true), [create(type, status: :failed, allow_failure: true),
create(type, status: :canceled)] create(type, status: :canceled)]
end end
...@@ -83,7 +77,7 @@ describe HasStatus do ...@@ -83,7 +77,7 @@ describe HasStatus do
end end
context 'one running one canceled' do context 'one running one canceled' do
let(:statuses) do let!(:statuses) do
[create(type, status: :running), create(type, status: :canceled)] [create(type, status: :running), create(type, status: :canceled)]
end end
...@@ -91,14 +85,15 @@ describe HasStatus do ...@@ -91,14 +85,15 @@ describe HasStatus do
end end
context 'all canceled' do context 'all canceled' do
let(:statuses) do let!(:statuses) do
[create(type, status: :canceled), create(type, status: :canceled)] [create(type, status: :canceled), create(type, status: :canceled)]
end end
it { is_expected.to eq 'canceled' } it { is_expected.to eq 'canceled' }
end end
context 'success and canceled but allowed to fail' do context 'success and canceled but allowed to fail' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), [create(type, status: :success),
create(type, status: :canceled, allow_failure: true)] create(type, status: :canceled, allow_failure: true)]
end end
...@@ -107,7 +102,7 @@ describe HasStatus do ...@@ -107,7 +102,7 @@ describe HasStatus do
end end
context 'one finished and second running but allowed to fail' do context 'one finished and second running but allowed to fail' do
let(:statuses) do let!(:statuses) do
[create(type, status: :success), [create(type, status: :success),
create(type, status: :running, allow_failure: true)] create(type, status: :running, allow_failure: true)]
end end
...@@ -118,11 +113,13 @@ describe HasStatus do ...@@ -118,11 +113,13 @@ describe HasStatus do
context 'ci build statuses' do context 'ci build statuses' do
let(:type) { :ci_build } let(:type) { :ci_build }
it_behaves_like 'build status summary' it_behaves_like 'build status summary'
end end
context 'generic commit statuses' do context 'generic commit statuses' do
let(:type) { :generic_commit_status } let(:type) { :generic_commit_status }
it_behaves_like 'build status summary' it_behaves_like 'build status summary'
end end
end end
......
...@@ -18,7 +18,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -18,7 +18,7 @@ describe Ci::ProcessPipelineService, services: true do
all_builds.where.not(status: [:created, :skipped]) all_builds.where.not(status: [:created, :skipped])
end end
def create_builds def process_pipeline
described_class.new(pipeline.project, user).execute(pipeline) described_class.new(pipeline.project, user).execute(pipeline)
end end
...@@ -36,26 +36,26 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -36,26 +36,26 @@ describe Ci::ProcessPipelineService, services: true do
end end
it 'processes a pipeline' do it 'processes a pipeline' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
succeed_pending succeed_pending
expect(builds.success.count).to eq(2) expect(builds.success.count).to eq(2)
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
succeed_pending succeed_pending
expect(builds.success.count).to eq(4) expect(builds.success.count).to eq(4)
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
succeed_pending succeed_pending
expect(builds.success.count).to eq(5) expect(builds.success.count).to eq(5)
expect(create_builds).to be_falsey expect(process_pipeline).to be_falsey
end end
it 'does not process pipeline if existing stage is running' do it 'does not process pipeline if existing stage is running' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pending.count).to eq(2) expect(builds.pending.count).to eq(2)
expect(create_builds).to be_falsey expect(process_pipeline).to be_falsey
expect(builds.pending.count).to eq(2) expect(builds.pending.count).to eq(2)
end end
end end
...@@ -67,7 +67,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -67,7 +67,7 @@ describe Ci::ProcessPipelineService, services: true do
end end
it 'automatically triggers a next stage when build finishes' do it 'automatically triggers a next stage when build finishes' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:status)).to contain_exactly('pending') expect(builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:drop) pipeline.builds.running_or_pending.each(&:drop)
...@@ -88,7 +88,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -88,7 +88,7 @@ describe Ci::ProcessPipelineService, services: true do
context 'when builds are successful' do context 'when builds are successful' do
it 'properly creates builds' do it 'properly creates builds' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:name)).to contain_exactly('build') expect(builds.pluck(:name)).to contain_exactly('build')
expect(builds.pluck(:status)).to contain_exactly('pending') expect(builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success) pipeline.builds.running_or_pending.each(&:success)
...@@ -113,7 +113,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -113,7 +113,7 @@ describe Ci::ProcessPipelineService, services: true do
context 'when test job fails' do context 'when test job fails' do
it 'properly creates builds' do it 'properly creates builds' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:name)).to contain_exactly('build') expect(builds.pluck(:name)).to contain_exactly('build')
expect(builds.pluck(:status)).to contain_exactly('pending') expect(builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success) pipeline.builds.running_or_pending.each(&:success)
...@@ -138,7 +138,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -138,7 +138,7 @@ describe Ci::ProcessPipelineService, services: true do
context 'when test and test_failure jobs fail' do context 'when test and test_failure jobs fail' do
it 'properly creates builds' do it 'properly creates builds' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:name)).to contain_exactly('build') expect(builds.pluck(:name)).to contain_exactly('build')
expect(builds.pluck(:status)).to contain_exactly('pending') expect(builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success) pipeline.builds.running_or_pending.each(&:success)
...@@ -164,7 +164,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -164,7 +164,7 @@ describe Ci::ProcessPipelineService, services: true do
context 'when deploy job fails' do context 'when deploy job fails' do
it 'properly creates builds' do it 'properly creates builds' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:name)).to contain_exactly('build') expect(builds.pluck(:name)).to contain_exactly('build')
expect(builds.pluck(:status)).to contain_exactly('pending') expect(builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success) pipeline.builds.running_or_pending.each(&:success)
...@@ -189,7 +189,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -189,7 +189,7 @@ describe Ci::ProcessPipelineService, services: true do
context 'when build is canceled in the second stage' do context 'when build is canceled in the second stage' do
it 'does not schedule builds after build has been canceled' do it 'does not schedule builds after build has been canceled' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:name)).to contain_exactly('build') expect(builds.pluck(:name)).to contain_exactly('build')
expect(builds.pluck(:status)).to contain_exactly('pending') expect(builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success) pipeline.builds.running_or_pending.each(&:success)
...@@ -208,7 +208,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -208,7 +208,7 @@ describe Ci::ProcessPipelineService, services: true do
context 'when listing manual actions' do context 'when listing manual actions' do
it 'returns only for skipped builds' do it 'returns only for skipped builds' do
# currently all builds are created # currently all builds are created
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(manual_actions).to be_empty expect(manual_actions).to be_empty
# succeed stage build # succeed stage build
...@@ -230,6 +230,69 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -230,6 +230,69 @@ describe Ci::ProcessPipelineService, services: true do
end end
end end
context 'when there are manual/on_failure jobs in earlier stages' do
before do
builds
process_pipeline
builds.each(&:reload)
end
context 'when first stage has only manual jobs' do
let(:builds) do
[create_build('build', 0, 'manual'),
create_build('check', 1),
create_build('test', 2)]
end
it 'starts from the second stage' do
expect(builds.map(&:status)).to eq(%w[skipped pending created])
end
end
context 'when second stage has only manual jobs' do
let(:builds) do
[create_build('check', 0),
create_build('build', 1, 'manual'),
create_build('test', 2)]
end
it 'skips second stage and continues on third stage' do
expect(builds.map(&:status)).to eq(%w[pending created created])
builds.first.success
builds.each(&:reload)
expect(builds.map(&:status)).to eq(%w[success skipped pending])
end
end
context 'when second stage has only on_failure jobs' do
let(:builds) do
[create_build('check', 0),
create_build('build', 1, 'on_failure'),
create_build('test', 2)]
end
it 'skips second stage and continues on third stage' do
expect(builds.map(&:status)).to eq(%w[pending created created])
builds.first.success
builds.each(&:reload)
expect(builds.map(&:status)).to eq(%w[success skipped pending])
end
end
def create_build(name, stage_idx, when_value = nil)
create(:ci_build,
:created,
pipeline: pipeline,
name: name,
stage_idx: stage_idx,
when: when_value)
end
end
context 'when failed build in the middle stage is retried' do context 'when failed build in the middle stage is retried' do
context 'when failed build is the only unsuccessful build in the stage' do context 'when failed build is the only unsuccessful build in the stage' do
before do before do
...@@ -242,7 +305,7 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -242,7 +305,7 @@ describe Ci::ProcessPipelineService, services: true do
end end
it 'does trigger builds in the next stage' do it 'does trigger builds in the next stage' do
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pluck(:name)).to contain_exactly('build:1', 'build:2') expect(builds.pluck(:name)).to contain_exactly('build:1', 'build:2')
pipeline.builds.running_or_pending.each(&:success) pipeline.builds.running_or_pending.each(&:success)
...@@ -297,14 +360,14 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -297,14 +360,14 @@ describe Ci::ProcessPipelineService, services: true do
expect(all_builds.count).to eq(2) expect(all_builds.count).to eq(2)
# Create builds will mark the created as pending # Create builds will mark the created as pending
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.count).to eq(2) expect(builds.count).to eq(2)
expect(all_builds.count).to eq(2) expect(all_builds.count).to eq(2)
# When we builds succeed we will create a rest of pipeline from .gitlab-ci.yml # When we builds succeed we will create a rest of pipeline from .gitlab-ci.yml
# We will have 2 succeeded, 2 pending (from stage test), total 5 (one more build from deploy) # We will have 2 succeeded, 2 pending (from stage test), total 5 (one more build from deploy)
succeed_pending succeed_pending
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.success.count).to eq(2) expect(builds.success.count).to eq(2)
expect(builds.pending.count).to eq(2) expect(builds.pending.count).to eq(2)
expect(all_builds.count).to eq(5) expect(all_builds.count).to eq(5)
...@@ -312,14 +375,14 @@ describe Ci::ProcessPipelineService, services: true do ...@@ -312,14 +375,14 @@ describe Ci::ProcessPipelineService, services: true do
# When we succeed the 2 pending from stage test, # When we succeed the 2 pending from stage test,
# We will queue a deploy stage, no new builds will be created # We will queue a deploy stage, no new builds will be created
succeed_pending succeed_pending
expect(create_builds).to be_truthy expect(process_pipeline).to be_truthy
expect(builds.pending.count).to eq(1) expect(builds.pending.count).to eq(1)
expect(builds.success.count).to eq(4) expect(builds.success.count).to eq(4)
expect(all_builds.count).to eq(5) expect(all_builds.count).to eq(5)
# When we succeed last pending build, we will have a total of 5 succeeded builds, no new builds will be created # When we succeed last pending build, we will have a total of 5 succeeded builds, no new builds will be created
succeed_pending succeed_pending
expect(create_builds).to be_falsey expect(process_pipeline).to be_falsey
expect(builds.success.count).to eq(5) expect(builds.success.count).to eq(5)
expect(all_builds.count).to eq(5) expect(all_builds.count).to eq(5)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment