spec/lib/release_tools/tasks/auto_build/timer_spec.rb (201 lines of code) (raw):
# frozen_string_literal: true
require 'spec_helper'
require 'release_tools/tasks'
RSpec.describe ReleaseTools::Tasks::AutoBuild::Timer do
subject(:task) { described_class.new }
let(:schedule_env) { '0, 3, 6,21' }
around do |ex|
ClimateControl.modify(AUTO_DEPLOY_SCHEDULE: schedule_env) do
ex.run
end
end
describe '#execute' do
let(:prepare_task) { instance_double(ReleaseTools::Tasks::AutoBuild::Prepare) }
let(:tag_task) { instance_double(ReleaseTools::Tasks::AutoDeploy::Tag) }
let(:pick_service) { instance_double(ReleaseTools::CherryPick::AutoDeployService) }
let(:current_auto_deploy_branch) { 'auto-deploy-01' }
let(:new_auto_deploy_branch) { 'auto-deploy-02' }
tests = [
{
auto_build_time: true,
no_auto_deploy_branch: true,
should_prepare: true
},
{
auto_build_time: true,
no_auto_deploy_branch: false,
should_prepare: false
},
{
auto_build_time: false,
no_auto_deploy_branch: false,
should_prepare: false
},
{
auto_build_time: false,
no_auto_deploy_branch: true,
should_prepare: false
}
]
before do
allow(ReleaseTools::Tasks::AutoBuild::Prepare).to receive(:new).and_return(prepare_task)
allow(ReleaseTools::Tasks::AutoDeploy::Tag).to receive(:new).and_return(tag_task)
allow(task).to receive_messages(auto_build_time?: auto_build_time, no_auto_deploy_branch?: no_auto_deploy_branch)
end
around do |ex|
ClimateControl.modify(AUTO_DEPLOY_BRANCH: current_auto_deploy_branch) do
ex.run
end
end
tests.each do |test_case|
context "when auto_build_time: #{test_case[:auto_build_time]} no_auto_deploy_branch: #{test_case[:no_auto_deploy_branch]}" do
let(:auto_build_time) { test_case[:auto_build_time] }
let(:no_auto_deploy_branch) { test_case[:no_auto_deploy_branch] }
it 'correctly handles prepare, pick, and tag' do
branch_name = current_auto_deploy_branch
if test_case[:should_prepare]
expect(prepare_task).to receive(:execute).and_return(
[
ReleaseTools::Services::AutoDeployBranchService::Result.new(
ReleaseTools::Project::GitlabEe.auto_deploy_path,
new_auto_deploy_branch,
build(:branch, name: new_auto_deploy_branch),
false
)
]
)
branch_name = new_auto_deploy_branch
else
expect(prepare_task).not_to receive(:execute)
end
expect(ReleaseTools::CherryPick::AutoDeployService).to receive(:new).with(ReleaseTools::Project::GitlabEe, branch_name).and_return(pick_service)
expect(ReleaseTools::CherryPick::AutoDeployService).to receive(:new).with(ReleaseTools::Project::OmnibusGitlab, branch_name).and_return(pick_service)
expect(ReleaseTools::CherryPick::AutoDeployService).to receive(:new).with(ReleaseTools::Project::CNGImage, branch_name).and_return(pick_service)
expect(pick_service).to receive(:execute).exactly(3)
expect(tag_task).to receive(:execute)
task.execute
end
end
end
context 'when there are no new commits and auto deploy branch is not created' do
let(:auto_build_time) { true }
let(:no_auto_deploy_branch) { true }
let(:pick_service) { instance_spy(ReleaseTools::CherryPick::AutoDeployService) }
let(:tag_task) { instance_spy(ReleaseTools::Tasks::AutoDeploy::Tag) }
before do
allow(ReleaseTools::CherryPick::AutoDeployService).to receive(:new).and_return(pick_service)
end
it 'does not modify AUTO_DEPLOY_BRANCH' do
expect(ENV.fetch('AUTO_DEPLOY_BRANCH', nil)).to eq(current_auto_deploy_branch)
expect(prepare_task).to receive(:execute).and_return([])
task.execute
expect(ENV.fetch('AUTO_DEPLOY_BRANCH', nil)).to eq(current_auto_deploy_branch)
end
end
context 'with TAG_PACKAGERS_ONLY' do
let(:auto_build_time) { true }
let(:no_auto_deploy_branch) { false }
it 'tags packagers only' do
allow(tag_task).to receive(:execute)
allow(ReleaseTools::CherryPick::AutoDeployService).to receive(:new).and_return(pick_service)
allow(pick_service).to receive(:execute)
expect(ReleaseTools::Tasks::AutoDeploy::Tag).to receive(:new).with(packagers_only: true)
ClimateControl.modify(TAG_PACKAGERS_ONLY: 'true') do
task.execute
end
end
end
end
describe '#schedule' do
it 'returns an array of integers' do
expect(task.schedule).to eq([0, 3, 6, 21])
end
context 'when AUTO_DEPLOY_SCHEDULE is not set' do
let(:schedule_env) { nil }
it 'raise an error' do
expect { task.schedule }.to raise_error('Missing schedule definition in AUTO_DEPLOY_SCHEDULE')
end
end
context 'when AUTO_DEPLOY_SCHEDULE is empty' do
let(:schedule_env) { '' }
# this is important for manual pipelines that disable the schedule and
# only perform pick and tag
it 'returns an empty array' do
expect(task.schedule).to be_empty
end
end
context 'when AUTO_DEPLOY_SCHEDULE contains unexpected characters' do
let(:schedule_env) { '0,f,3' }
it 'raise an error' do
expect { task.schedule }.to raise_error(ArgumentError)
end
end
context 'when AUTO_DEPLOY_SCHEDULE contains more than 24 hours' do
let(:schedule_env) { (0..66).to_a.join(',') }
it 'raise an error' do
expect { task.schedule }.to raise_error(ArgumentError)
end
end
context 'when AUTO_DEPLOY_SCHEDULE contains number higher than 23' do
let(:schedule_env) { '0,24,5' }
it 'raise an error' do
expect { task.schedule }.to raise_error(ArgumentError, '24 is not a valid hour of the day')
end
end
context 'when AUTO_DEPLOY_SCHEDULE contains negative numbers' do
let(:schedule_env) { '9,-6,5' }
it 'raise an error' do
expect { task.schedule }.to raise_error(ArgumentError, '-6 is not a valid hour of the day')
end
end
end
describe '#auto_build_time?' do
it 'is auto build time when hour matches the schedule' do
schedule_env.split(',') do |hour|
now = Time.utc(2023, 5, 3, hour.to_i, 45)
Timecop.travel(now) do
expect(task).to be_auto_build_time
end
end
end
it 'is not auto build time when hour is outside of the schedule' do
0.upto(23) do |hour|
next if task.schedule.include?(hour)
now = Time.utc(2023, 5, 3, hour.to_i, 45)
Timecop.travel(now) do
expect(task).not_to be_auto_build_time
end
end
end
it 'is not auto build time on weekend' do
0.upto(23) do |hour|
saturday = Time.utc(2023, 4, 29, hour.to_i, 45)
Timecop.travel(saturday) do
expect(task).not_to be_auto_build_time
end
Timecop.travel(saturday + 1.day) do
expect(task).not_to be_auto_build_time
end
end
end
it 'can be forced true with CREATE_AUTO_DEPLOY_BRANCH_SCHEDULE' do
ClimateControl.modify(CREATE_AUTO_DEPLOY_BRANCH_SCHEDULE: '1') do
saturday = Time.utc(2023, 4, 29)
Timecop.travel(saturday) do
expect(task).to be_auto_build_time
end
end
end
end
describe '#no_auto_deploy_branch?' do
it 'returns true when the current auto-deploy branch does not exist' do
branch = '16-0-auto-deploy-2023050308'
expect(ReleaseTools::AutoDeploy::Naming).to receive(:branch).and_return(branch)
expect(ReleaseTools::GitlabClient).to receive(:find_branch).with(branch, ReleaseTools::Project::GitlabEe.auto_deploy_path).and_return(nil)
expect(task).to be_no_auto_deploy_branch
end
it 'returns false when the current auto-deploy branch exists' do
branch = '16-0-auto-deploy-2023050308'
expect(ReleaseTools::AutoDeploy::Naming).to receive(:branch).and_return(branch)
expect(ReleaseTools::GitlabClient).to receive(:find_branch).with(branch, ReleaseTools::Project::GitlabEe.auto_deploy_path).and_return(build(:branch))
expect(task).not_to be_no_auto_deploy_branch
end
end
end