From f262b8f320c2f6760cc978ef946c7c2b5b440a58 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Wed, 10 Oct 2018 16:01:04 +0900 Subject: Improve specs for Ci::ProcessBuildService --- spec/services/ci/process_build_service_spec.rb | 251 +++++++++---------------- 1 file changed, 90 insertions(+), 161 deletions(-) diff --git a/spec/services/ci/process_build_service_spec.rb b/spec/services/ci/process_build_service_spec.rb index 9f47439dc4a..3c730c07457 100644 --- a/spec/services/ci/process_build_service_spec.rb +++ b/spec/services/ci/process_build_service_spec.rb @@ -2,141 +2,40 @@ require 'spec_helper' describe Ci::ProcessBuildService, '#execute' do + VALID_STATUSES_WHEN_ON_SUCCESS = %w[success skipped].freeze + VALID_STATUSES_WHEN_ON_FAILURE = %w[failed].freeze + VALID_STATUSES_WHEN_ALWAYS = %w[success failed skipped].freeze + VALID_STATUSES_WHEN_MANUAL = %w[success skipped].freeze + VALID_STATUSES_WHEN_DELAYED = %w[success skipped].freeze + SKIPPABLE_STATUES = %w[created pending].freeze + let(:user) { create(:user) } let(:project) { create(:project) } - subject { described_class.new(project, user).execute(build, current_status) } + subject { described_class.new(project, user).execute(build, status_for_prior_stages) } before do project.add_maintainer(user) end - shared_examples_for 'Enqueuing properly' do |valid_statuses_for_when| - valid_statuses_for_when.each do |status_for_prior_stages| - context "when status for prior stages is #{status_for_prior_stages}" do - let(:current_status) { status_for_prior_stages } - - %w[created skipped manual scheduled].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) } - - it 'enqueues the build' do - expect { subject }.to change { build.status }.to('pending') - end - end - end - - %w[pending running success failed canceled].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) } - - it 'does not change the build status' do - expect { subject }.not_to change { build.status } - end - end - end - end - end - - (HasStatus::AVAILABLE_STATUSES - valid_statuses_for_when).each do |status_for_prior_stages| - let(:current_status) { status_for_prior_stages } - - context "when status for prior stages is #{status_for_prior_stages}" do - %w[created pending].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) } - - it 'skips the build' do - expect { subject }.to change { build.status }.to('skipped') - end - end - end - - (HasStatus::AVAILABLE_STATUSES - %w[created pending]).each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) } - - it 'does not change build status' do - expect { subject }.not_to change { build.status } - end - end - end - end - end - end - - shared_examples_for 'Actionizing properly' do |valid_statuses_for_when| - valid_statuses_for_when.each do |status_for_prior_stages| - context "when status for prior stages is #{status_for_prior_stages}" do - let(:current_status) { status_for_prior_stages } - - %w[created].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) } - - it 'enqueues the build' do - expect { subject }.to change { build.status }.to('manual') - end - end - end - - %w[manual skipped pending running success failed canceled scheduled].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) } - - it 'does not change the build status' do - expect { subject }.not_to change { build.status } - end - end - end - end - end - - (HasStatus::AVAILABLE_STATUSES - valid_statuses_for_when).each do |status_for_prior_stages| - let(:current_status) { status_for_prior_stages } - - context "when status for prior stages is #{status_for_prior_stages}" do - %w[created pending].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) } - - it 'skips the build' do - expect { subject }.to change { build.status }.to('skipped') - end - end - end - - (HasStatus::AVAILABLE_STATUSES - %w[created pending]).each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) } - - it 'does not change build status' do - expect { subject }.not_to change { build.status } - end - end - end - end - end - end - - shared_examples_for 'Scheduling properly' do |valid_statuses_for_when| - valid_statuses_for_when.each do |status_for_prior_stages| - context "when status for prior stages is #{status_for_prior_stages}" do - let(:current_status) { status_for_prior_stages } + shared_examples_for 'Change the build status' do |when_option: nil, current_statuses: nil, from_statuses:, to_status:, factory_options: nil| + current_statuses.each do |current_status| + context "when status for prior stages is #{current_status}" do + let(:status_for_prior_stages) { current_status } - %w[created].each do |status| + from_statuses.each do |status| context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) } + let(:build) { create(:ci_build, status.to_sym, *factory_options, when: when_option, user: user, project: project) } - it 'enqueues the build' do - expect { subject }.to change { build.status }.to('scheduled') + it 'changes the build status' do + expect { subject }.to change { build.status }.to(to_status) end end end - %w[manual skipped pending running success failed canceled scheduled].each do |status| + (HasStatus::AVAILABLE_STATUSES - from_statuses).each do |status| context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) } + let(:build) { create(:ci_build, status.to_sym, *factory_options, when: when_option, user: user, project: project) } it 'does not change the build status' do expect { subject }.not_to change { build.status } @@ -145,61 +44,67 @@ describe Ci::ProcessBuildService, '#execute' do end end end - - (HasStatus::AVAILABLE_STATUSES - valid_statuses_for_when).each do |status_for_prior_stages| - let(:current_status) { status_for_prior_stages } - - context "when status for prior stages is #{status_for_prior_stages}" do - %w[created pending].each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) } - - it 'skips the build' do - expect { subject }.to change { build.status }.to('skipped') - end - end - end - - (HasStatus::AVAILABLE_STATUSES - %w[created pending]).each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) } - - it 'does not change build status' do - expect { subject }.not_to change { build.status } - end - end - end - end - end end context 'when build has on_success option' do - let(:when_option) { :on_success } - - it_behaves_like 'Enqueuing properly', %w[success skipped] + it_behaves_like 'Change the build status', + when_option: :on_success, + current_statuses: VALID_STATUSES_WHEN_ON_SUCCESS, + from_statuses: %w[created skipped manual scheduled], + to_status: 'pending' + + it_behaves_like 'Change the build status', + when_option: :on_success, + current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), + from_statuses: SKIPPABLE_STATUES, + to_status: 'skipped' end context 'when build has on_failure option' do - let(:when_option) { :on_failure } - - it_behaves_like 'Enqueuing properly', %w[failed] + it_behaves_like 'Change the build status', + when_option: :on_failure, + current_statuses: VALID_STATUSES_WHEN_ON_FAILURE, + from_statuses: %w[created skipped manual scheduled], + to_status: 'pending' + + it_behaves_like 'Change the build status', + when_option: :on_failure, + current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_FAILURE), + from_statuses: SKIPPABLE_STATUES, + to_status: 'skipped' end context 'when build has always option' do - let(:when_option) { :always } - - it_behaves_like 'Enqueuing properly', %w[success failed skipped] + it_behaves_like 'Change the build status', + when_option: :always, + current_statuses: VALID_STATUSES_WHEN_ALWAYS, + from_statuses: %w[created skipped manual scheduled], + to_status: 'pending' + + it_behaves_like 'Change the build status', + when_option: :always, + current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ALWAYS), + from_statuses: SKIPPABLE_STATUES, + to_status: 'skipped' end context 'when build has manual option' do - let(:when_option) { :manual } - - it_behaves_like 'Actionizing properly', %w[success skipped] + it_behaves_like 'Change the build status', + when_option: :manual, + current_statuses: VALID_STATUSES_WHEN_MANUAL, + from_statuses: %w[created], + to_status: 'manual', + factory_options: %i[actionable] + + it_behaves_like 'Change the build status', + when_option: :manual, + current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), + from_statuses: SKIPPABLE_STATUES, + to_status: 'skipped', + factory_options: %i[actionable] end context 'when build has delayed option' do - let(:when_option) { :delayed } - before do allow(Ci::BuildScheduleWorker).to receive(:perform_at) { } end @@ -209,7 +114,19 @@ describe Ci::ProcessBuildService, '#execute' do stub_feature_flags(ci_enable_scheduled_build: true) end - it_behaves_like 'Scheduling properly', %w[success skipped] + it_behaves_like 'Change the build status', + when_option: :delayed, + current_statuses: VALID_STATUSES_WHEN_DELAYED, + from_statuses: %w[created], + to_status: 'scheduled', + factory_options: %i[schedulable] + + it_behaves_like 'Change the build status', + when_option: :delayed, + current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), + from_statuses: SKIPPABLE_STATUES, + to_status: 'skipped', + factory_options: %i[schedulable] end context 'when ci_enable_scheduled_build is enabled' do @@ -217,7 +134,19 @@ describe Ci::ProcessBuildService, '#execute' do stub_feature_flags(ci_enable_scheduled_build: false) end - it_behaves_like 'Actionizing properly', %w[success skipped] + it_behaves_like 'Change the build status', + when_option: :delayed, + current_statuses: VALID_STATUSES_WHEN_DELAYED, + from_statuses: %w[created], + to_status: 'manual', + factory_options: %i[schedulable] + + it_behaves_like 'Change the build status', + when_option: :delayed, + current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), + from_statuses: SKIPPABLE_STATUES, + to_status: 'skipped', + factory_options: %i[schedulable] end end end -- cgit v1.2.1 From 995d2d13a3e3aea2cd68ebf4a4017a597b0428f2 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 18 Oct 2018 15:07:27 +0900 Subject: Simplify the spec --- spec/services/ci/process_build_service_spec.rb | 201 ++++++++++++------------- 1 file changed, 97 insertions(+), 104 deletions(-) diff --git a/spec/services/ci/process_build_service_spec.rb b/spec/services/ci/process_build_service_spec.rb index 3c730c07457..9a53b32394d 100644 --- a/spec/services/ci/process_build_service_spec.rb +++ b/spec/services/ci/process_build_service_spec.rb @@ -2,106 +2,93 @@ require 'spec_helper' describe Ci::ProcessBuildService, '#execute' do - VALID_STATUSES_WHEN_ON_SUCCESS = %w[success skipped].freeze - VALID_STATUSES_WHEN_ON_FAILURE = %w[failed].freeze - VALID_STATUSES_WHEN_ALWAYS = %w[success failed skipped].freeze - VALID_STATUSES_WHEN_MANUAL = %w[success skipped].freeze - VALID_STATUSES_WHEN_DELAYED = %w[success skipped].freeze - SKIPPABLE_STATUES = %w[created pending].freeze - let(:user) { create(:user) } let(:project) { create(:project) } - subject { described_class.new(project, user).execute(build, status_for_prior_stages) } + subject { described_class.new(project, user).execute(build, current_status) } before do project.add_maintainer(user) end - shared_examples_for 'Change the build status' do |when_option: nil, current_statuses: nil, from_statuses:, to_status:, factory_options: nil| - current_statuses.each do |current_status| - context "when status for prior stages is #{current_status}" do - let(:status_for_prior_stages) { current_status } + context 'when build has on_success option' do + let(:build) { create(:ci_build, :created, when: :on_success, user: user, project: project) } - from_statuses.each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, *factory_options, when: when_option, user: user, project: project) } + context 'when current status is success' do + let(:current_status) { 'success' } - it 'changes the build status' do - expect { subject }.to change { build.status }.to(to_status) - end - end - end + it 'changes the build status' do + expect { subject }.to change { build.status }.to('pending') + end + end - (HasStatus::AVAILABLE_STATUSES - from_statuses).each do |status| - context "when build status is #{status}" do - let(:build) { create(:ci_build, status.to_sym, *factory_options, when: when_option, user: user, project: project) } + context 'when current status is failed' do + let(:current_status) { 'failed' } - it 'does not change the build status' do - expect { subject }.not_to change { build.status } - end - end - end + it 'does not change the build status' do + expect { subject }.to change { build.status }.to('skipped') end end end - context 'when build has on_success option' do - it_behaves_like 'Change the build status', - when_option: :on_success, - current_statuses: VALID_STATUSES_WHEN_ON_SUCCESS, - from_statuses: %w[created skipped manual scheduled], - to_status: 'pending' - - it_behaves_like 'Change the build status', - when_option: :on_success, - current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), - from_statuses: SKIPPABLE_STATUES, - to_status: 'skipped' - end - context 'when build has on_failure option' do - it_behaves_like 'Change the build status', - when_option: :on_failure, - current_statuses: VALID_STATUSES_WHEN_ON_FAILURE, - from_statuses: %w[created skipped manual scheduled], - to_status: 'pending' - - it_behaves_like 'Change the build status', - when_option: :on_failure, - current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_FAILURE), - from_statuses: SKIPPABLE_STATUES, - to_status: 'skipped' + let(:build) { create(:ci_build, :created, when: :on_failure, user: user, project: project) } + + context 'when current status is success' do + let(:current_status) { 'success' } + + it 'changes the build status' do + expect { subject }.to change { build.status }.to('skipped') + end + end + + context 'when current status is failed' do + let(:current_status) { 'failed' } + + it 'does not change the build status' do + expect { subject }.to change { build.status }.to('pending') + end + end end context 'when build has always option' do - it_behaves_like 'Change the build status', - when_option: :always, - current_statuses: VALID_STATUSES_WHEN_ALWAYS, - from_statuses: %w[created skipped manual scheduled], - to_status: 'pending' - - it_behaves_like 'Change the build status', - when_option: :always, - current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ALWAYS), - from_statuses: SKIPPABLE_STATUES, - to_status: 'skipped' + let(:build) { create(:ci_build, :created, when: :always, user: user, project: project) } + + context 'when current status is success' do + let(:current_status) { 'success' } + + it 'changes the build status' do + expect { subject }.to change { build.status }.to('pending') + end + end + + context 'when current status is failed' do + let(:current_status) { 'failed' } + + it 'does not change the build status' do + expect { subject }.to change { build.status }.to('pending') + end + end end context 'when build has manual option' do - it_behaves_like 'Change the build status', - when_option: :manual, - current_statuses: VALID_STATUSES_WHEN_MANUAL, - from_statuses: %w[created], - to_status: 'manual', - factory_options: %i[actionable] - - it_behaves_like 'Change the build status', - when_option: :manual, - current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), - from_statuses: SKIPPABLE_STATUES, - to_status: 'skipped', - factory_options: %i[actionable] + let(:build) { create(:ci_build, :created, :actionable, user: user, project: project) } + + context 'when current status is success' do + let(:current_status) { 'success' } + + it 'changes the build status' do + expect { subject }.to change { build.status }.to('manual') + end + end + + context 'when current status is failed' do + let(:current_status) { 'failed' } + + it 'does not change the build status' do + expect { subject }.to change { build.status }.to('skipped') + end + end end context 'when build has delayed option' do @@ -109,44 +96,50 @@ describe Ci::ProcessBuildService, '#execute' do allow(Ci::BuildScheduleWorker).to receive(:perform_at) { } end + let(:build) { create(:ci_build, :created, :schedulable, user: user, project: project) } + context 'when ci_enable_scheduled_build is enabled' do before do stub_feature_flags(ci_enable_scheduled_build: true) end - it_behaves_like 'Change the build status', - when_option: :delayed, - current_statuses: VALID_STATUSES_WHEN_DELAYED, - from_statuses: %w[created], - to_status: 'scheduled', - factory_options: %i[schedulable] - - it_behaves_like 'Change the build status', - when_option: :delayed, - current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), - from_statuses: SKIPPABLE_STATUES, - to_status: 'skipped', - factory_options: %i[schedulable] + context 'when current status is success' do + let(:current_status) { 'success' } + + it 'changes the build status' do + expect { subject }.to change { build.status }.to('scheduled') + end + end + + context 'when current status is failed' do + let(:current_status) { 'failed' } + + it 'does not change the build status' do + expect { subject }.to change { build.status }.to('skipped') + end + end end - context 'when ci_enable_scheduled_build is enabled' do + context 'when ci_enable_scheduled_build is disabled' do before do stub_feature_flags(ci_enable_scheduled_build: false) end - it_behaves_like 'Change the build status', - when_option: :delayed, - current_statuses: VALID_STATUSES_WHEN_DELAYED, - from_statuses: %w[created], - to_status: 'manual', - factory_options: %i[schedulable] - - it_behaves_like 'Change the build status', - when_option: :delayed, - current_statuses: (HasStatus::AVAILABLE_STATUSES - VALID_STATUSES_WHEN_ON_SUCCESS), - from_statuses: SKIPPABLE_STATUES, - to_status: 'skipped', - factory_options: %i[schedulable] + context 'when current status is success' do + let(:current_status) { 'success' } + + it 'changes the build status' do + expect { subject }.to change { build.status }.to('manual') + end + end + + context 'when current status is failed' do + let(:current_status) { 'failed' } + + it 'does not change the build status' do + expect { subject }.to change { build.status }.to('skipped') + end + end end end end -- cgit v1.2.1