spec/lib/release_tools/services/branches_status_service_spec.rb (280 lines of code) (raw):
# frozen_string_literal: true
require 'spec_helper'
describe ReleaseTools::Services::BranchesStatusService do
describe '#execute' do
subject(:branch_verifier) { described_class.new(release_type: release_type, versions: versions) }
let(:notifier) { stub_const('ReleaseTools::Slack::ReleaseJobEndNotifier', spy) }
let(:projects) { [ReleaseTools::Project::GitlabCe, ReleaseTools::Project::GitlabEe] }
let(:statuses) do
[
{ project_name: 'project_name', branch: 'branch_name', link: 'link', status: 'failed' }
]
end
before do
stub_const("ReleaseTools::Services::BranchesStatusService::PROJECTS", projects)
end
context "on monthly release" do
let(:release_type) { :monthly }
let(:versions) { [ReleaseTools::Version.new("15.9")] }
it "returns all stable branches are green on success status" do
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-9-stable',
release_type: :monthly
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-9-stable-ee',
release_type: :monthly
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(branch_verifier.logger).to receive(:info).with(/All branches are green/)
expect(notifier).to receive(:send_notification)
branch_verifier.execute
end
context 'when some statuses are not success and raises an exception' do
it 'outputs the component versions that are not successful' do
logger_output = "
❌ The following branches do not have green pipelines:
- gitlab-ce - 15-9-stable - failed: https://gitlab.com/gitlab-org/gitlab-foss/-/commits/15-9-stable
- gitlab-ee - 15-9-stable-ee - canceled: https://gitlab.com/gitlab-org/gitlab/-/commits/15-9-stable-ee"
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-9-stable',
release_type: :monthly
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-9-stable-ee',
release_type: :monthly
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'canceled'))
expect(branch_verifier.logger).to receive(:info).with(logger_output)
expect(notifier).to receive(:send_notification)
expect { branch_verifier.execute }.to raise_error(described_class::FailedBranchError)
end
end
context 'when the job is unable to complete and an error is raised' do
before do
allow(branch_verifier).to receive(:statuses).and_return(statuses)
end
it 'outputs manual instructions and raises an error' do
log_message = "Project status check failed. If this job continues to fail, the status of the projects can be checked manually:\n\n- project_name - branch_name: link"
allow(ReleaseTools::Services::ComponentStatusService).to receive(:new)
.and_raise(Gitlab::Error::Error)
expect(ReleaseTools::Slack::ReleaseJobEndNotifier).to receive(:new).with(
job_type: 'Branches Status',
status: :failed,
release_type: :monthly
).and_return(instance_double(ReleaseTools::Slack::ReleaseJobEndNotifier, send_notification: true))
expect(branch_verifier.logger).to receive(:fatal).with(log_message, error: anything)
expect { branch_verifier.execute }.to raise_error(Gitlab::Error::Error)
end
end
end
context "on patch release preparation" do
let(:release_type) { :patch }
let(:versions) { [ReleaseTools::Version.new("17.1"), ReleaseTools::Version.new("16.10"), ReleaseTools::Version.new("15.11")] }
before do
allow(branch_verifier).to receive(:projects).and_return(projects)
end
it "returns all branches are green on success status" do
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '17-1-stable',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '16-10-stable',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-11-stable',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '17-1-stable-ee',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '16-10-stable-ee',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-11-stable-ee',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(branch_verifier.logger).to receive(:info).with(/All branches are green/)
expect(notifier).to receive(:send_notification)
branch_verifier.execute
end
context 'when some statuses are not success and raises an exception' do
it 'outputs the component versions that are not successful' do
logger_output = "
❌ The following branches do not have green pipelines:
- gitlab-ce - 17-1-stable - failed: https://gitlab.com/gitlab-org/security/gitlab-foss/-/commits/17-1-stable
- gitlab-ce - 16-10-stable - failed: https://gitlab.com/gitlab-org/security/gitlab-foss/-/commits/16-10-stable
- gitlab-ce - 15-11-stable - failed: https://gitlab.com/gitlab-org/security/gitlab-foss/-/commits/15-11-stable
- gitlab-ee - 17-1-stable-ee - canceled: https://gitlab.com/gitlab-org/security/gitlab/-/commits/17-1-stable-ee
- gitlab-ee - 16-10-stable-ee - running: https://gitlab.com/gitlab-org/security/gitlab/-/commits/16-10-stable-ee
- gitlab-ee - 15-11-stable-ee - failed: https://gitlab.com/gitlab-org/security/gitlab/-/commits/15-11-stable-ee"
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '17-1-stable',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '16-10-stable',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-11-stable',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '17-1-stable-ee',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'canceled'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '16-10-stable-ee',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'running'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-11-stable-ee',
release_type: :patch
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(branch_verifier.logger).to receive(:info).with(logger_output)
expect(notifier).to receive(:send_notification)
expect(branch_verifier.logger).not_to receive(:fatal)
expect { branch_verifier.execute }.to raise_error(described_class::FailedBranchError)
end
end
context 'when the job is unable to complete and an error is raised' do
before do
allow(branch_verifier).to receive(:statuses).and_return(statuses)
allow(ReleaseTools::Services::ComponentStatusService).to receive(:new)
.and_raise(Gitlab::Error::Error)
end
it 'outputs manual instructions and raises an error' do
log_message = "Project status check failed. If this job continues to fail, the status of the projects can be checked manually:\n\n- project_name - branch_name: link"
expect(branch_verifier).to receive(:generate_link_list)
.with(projects, versions, release_type)
.and_yield('project_name', 'branch_name', 'link')
expect(ReleaseTools::Slack::ReleaseJobEndNotifier).to receive(:new).with(
job_type: 'Branches Status',
status: :failed,
release_type: :patch
).and_return(instance_double(ReleaseTools::Slack::ReleaseJobEndNotifier, send_notification: true))
expect(branch_verifier.logger).to receive(:fatal).with(log_message, error: anything)
expect { branch_verifier.execute }.to raise_error(Gitlab::Error::Error)
end
it 'does not log the failure message (info) and does not raise FailedBranchError' do
expect(branch_verifier.logger).not_to receive(:info)
expect { branch_verifier.execute }.not_to raise_error(described_class::FailedBranchError)
end
end
end
context "on internal release" do
let(:release_type) { :internal }
let(:versions) do
[
ReleaseTools::Version.new('15.2.1-internal1'),
ReleaseTools::Version.new('15.1.2-internal1')
]
end
before do
allow(branch_verifier).to receive(:projects).and_return(projects)
end
it "returns all branches are green on success status" do
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-2-stable',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-1-stable',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-2-stable-ee',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-1-stable-ee',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'success'))
expect(branch_verifier.logger).to receive(:info).with(/All branches are green/)
expect(notifier).to receive(:send_notification)
branch_verifier.execute
end
context 'when some statuses are not success and raises an exception' do
it 'outputs the component versions that are not successful' do
logger_output = "
❌ The following branches do not have green pipelines:
- gitlab-ce - 15-2-stable - failed: https://gitlab.com/gitlab-org/security/gitlab-foss/-/commits/15-2-stable
- gitlab-ce - 15-1-stable - failed: https://gitlab.com/gitlab-org/security/gitlab-foss/-/commits/15-1-stable
- gitlab-ee - 15-2-stable-ee - canceled: https://gitlab.com/gitlab-org/security/gitlab/-/commits/15-2-stable-ee
- gitlab-ee - 15-1-stable-ee - running: https://gitlab.com/gitlab-org/security/gitlab/-/commits/15-1-stable-ee"
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-2-stable',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.first,
branch: '15-1-stable',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'failed'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-2-stable-ee',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'canceled'))
expect(ReleaseTools::Services::ComponentStatusService).to receive(:new).with(
project: projects.second,
branch: '15-1-stable-ee',
release_type: :internal
).and_return(instance_double(ReleaseTools::Services::ComponentStatusService, execute: 'running'))
expect(branch_verifier.logger).to receive(:info).with(logger_output)
expect(notifier).to receive(:send_notification)
expect(branch_verifier.logger).not_to receive(:fatal)
expect { branch_verifier.execute }.to raise_error(described_class::FailedBranchError)
end
end
context 'when the job is unable to complete and an error is raised' do
before do
allow(branch_verifier).to receive(:statuses).and_return(statuses)
allow(ReleaseTools::Services::ComponentStatusService).to receive(:new)
.and_raise(StandardError)
end
it 'outputs manual instructions and raises an error' do
log_message = "Project status check failed. If this job continues to fail, the status of the projects can be checked manually:\n\n- project_name - branch_name: link"
expect(branch_verifier).to receive(:generate_link_list)
.with(projects, versions, release_type)
.and_yield('project_name', 'branch_name', 'link')
expect(ReleaseTools::Slack::ReleaseJobEndNotifier).to receive(:new).with(
job_type: 'Branches Status',
status: :failed,
release_type: :internal
).and_return(instance_double(ReleaseTools::Slack::ReleaseJobEndNotifier, send_notification: true))
expect(branch_verifier.logger).to receive(:fatal).with(log_message, error: anything)
expect { branch_verifier.execute }.to raise_error(StandardError)
end
end
it 'does not log the failure message (info) and does not raise FailedBranchError' do
expect(branch_verifier.logger).not_to receive(:info)
expect { branch_verifier.execute }.not_to raise_error(described_class::FailedBranchError)
end
end
end
end