debian-mirror-gitlab/spec/services/ci/after_requeue_job_service_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

321 lines
7.4 KiB
Ruby
Raw Normal View History

2021-04-29 21:17:54 +05:30
# frozen_string_literal: true
require 'spec_helper'
2022-05-07 20:08:51 +05:30
RSpec.describe Ci::AfterRequeueJobService, :sidekiq_inline do
let_it_be(:project) { create(:project, :empty_repo) }
2022-03-02 08:16:31 +05:30
let_it_be(:user) { project.first_owner }
2021-04-29 21:17:54 +05:30
2022-05-07 20:08:51 +05:30
before_all do
project.repository.create_file(user, 'init', 'init', message: 'init', branch_name: 'master')
end
2021-04-29 21:17:54 +05:30
2022-05-07 20:08:51 +05:30
subject(:service) { described_class.new(project, user) }
2022-01-26 12:08:38 +05:30
2022-05-07 20:08:51 +05:30
context 'stage-dag mixed pipeline' do
let(:config) do
<<-EOY
stages: [a, b, c]
2022-01-26 12:08:38 +05:30
2022-05-07 20:08:51 +05:30
a1:
stage: a
script: exit $(($RANDOM % 2))
a2:
stage: a
script: exit 0
needs: [a1]
2022-01-26 12:08:38 +05:30
2022-07-23 23:45:48 +05:30
a3:
stage: a
script: exit 0
needs: [a2]
2022-05-07 20:08:51 +05:30
b1:
stage: b
script: exit 0
needs: []
2022-01-26 12:08:38 +05:30
2022-05-07 20:08:51 +05:30
b2:
stage: b
script: exit 0
needs: [a2]
c1:
stage: c
script: exit 0
needs: [b2]
c2:
stage: c
script: exit 0
EOY
2022-01-26 12:08:38 +05:30
end
2021-04-29 21:17:54 +05:30
2022-05-07 20:08:51 +05:30
let(:pipeline) do
Ci::CreatePipelineService.new(project, user, { ref: 'master' }).execute(:push).payload
2021-09-30 23:02:18 +05:30
end
2022-05-07 20:08:51 +05:30
let(:a1) { find_job('a1') }
let(:b1) { find_job('b1') }
before do
stub_ci_pipeline_yaml_file(config)
check_jobs_statuses(
a1: 'pending',
a2: 'created',
2022-07-23 23:45:48 +05:30
a3: 'created',
2022-05-07 20:08:51 +05:30
b1: 'pending',
b2: 'created',
c1: 'created',
c2: 'created'
)
b1.success!
check_jobs_statuses(
a1: 'pending',
a2: 'created',
2022-07-23 23:45:48 +05:30
a3: 'created',
2022-05-07 20:08:51 +05:30
b1: 'success',
b2: 'created',
c1: 'created',
c2: 'created'
)
a1.drop!
check_jobs_statuses(
a1: 'failed',
a2: 'skipped',
2022-07-23 23:45:48 +05:30
a3: 'skipped',
2022-05-07 20:08:51 +05:30
b1: 'success',
b2: 'skipped',
c1: 'skipped',
c2: 'skipped'
)
2022-06-21 17:19:12 +05:30
new_a1 = Ci::RetryJobService.new(project, user).clone!(a1)
2022-05-07 20:08:51 +05:30
new_a1.enqueue!
check_jobs_statuses(
a1: 'pending',
a2: 'skipped',
2022-07-23 23:45:48 +05:30
a3: 'skipped',
2022-05-07 20:08:51 +05:30
b1: 'success',
b2: 'skipped',
c1: 'skipped',
c2: 'skipped'
)
2021-09-30 23:02:18 +05:30
end
2022-01-26 12:08:38 +05:30
2022-05-07 20:08:51 +05:30
it 'marks subsequent skipped jobs as processable' do
execute_after_requeue_service(a1)
check_jobs_statuses(
a1: 'pending',
a2: 'created',
2022-10-11 01:57:18 +05:30
a3: 'created',
2022-05-07 20:08:51 +05:30
b1: 'success',
b2: 'created',
c1: 'created',
c2: 'created'
)
end
2022-07-23 23:45:48 +05:30
context 'when executed by a different user than the original owner' do
let(:retryer) { create(:user).tap { |u| project.add_maintainer(u) } }
let(:service) { described_class.new(project, retryer) }
it 'reassigns jobs with updated statuses to the retryer' do
expect(jobs_name_status_owner_needs).to contain_exactly(
{ 'name' => 'a1', 'status' => 'pending', 'user_id' => user.id, 'needs' => [] },
{ 'name' => 'a2', 'status' => 'skipped', 'user_id' => user.id, 'needs' => ['a1'] },
{ 'name' => 'a3', 'status' => 'skipped', 'user_id' => user.id, 'needs' => ['a2'] },
{ 'name' => 'b1', 'status' => 'success', 'user_id' => user.id, 'needs' => [] },
{ 'name' => 'b2', 'status' => 'skipped', 'user_id' => user.id, 'needs' => ['a2'] },
{ 'name' => 'c1', 'status' => 'skipped', 'user_id' => user.id, 'needs' => ['b2'] },
{ 'name' => 'c2', 'status' => 'skipped', 'user_id' => user.id, 'needs' => [] }
)
execute_after_requeue_service(a1)
expect(jobs_name_status_owner_needs).to contain_exactly(
{ 'name' => 'a1', 'status' => 'pending', 'user_id' => user.id, 'needs' => [] },
{ 'name' => 'a2', 'status' => 'created', 'user_id' => retryer.id, 'needs' => ['a1'] },
2022-10-11 01:57:18 +05:30
{ 'name' => 'a3', 'status' => 'created', 'user_id' => retryer.id, 'needs' => ['a2'] },
2022-07-23 23:45:48 +05:30
{ 'name' => 'b1', 'status' => 'success', 'user_id' => user.id, 'needs' => [] },
{ 'name' => 'b2', 'status' => 'created', 'user_id' => retryer.id, 'needs' => ['a2'] },
{ 'name' => 'c1', 'status' => 'created', 'user_id' => retryer.id, 'needs' => ['b2'] },
{ 'name' => 'c2', 'status' => 'created', 'user_id' => retryer.id, 'needs' => [] }
)
end
end
2021-09-30 23:02:18 +05:30
end
2022-05-07 20:08:51 +05:30
context 'stage-dag mixed pipeline with some same-stage needs' do
let(:config) do
<<-EOY
stages: [a, b, c]
a1:
stage: a
script: exit $(($RANDOM % 2))
a2:
stage: a
script: exit 0
needs: [a1]
b1:
stage: b
script: exit 0
needs: [b2]
b2:
stage: b
script: exit 0
c1:
stage: c
script: exit 0
needs: [b2]
c2:
stage: c
script: exit 0
EOY
end
let(:pipeline) do
Ci::CreatePipelineService.new(project, user, { ref: 'master' }).execute(:push).payload
end
let(:a1) { find_job('a1') }
2021-04-29 21:17:54 +05:30
before do
2022-05-07 20:08:51 +05:30
stub_ci_pipeline_yaml_file(config)
check_jobs_statuses(
a1: 'pending',
a2: 'created',
b1: 'created',
b2: 'created',
c1: 'created',
c2: 'created'
)
a1.drop!
check_jobs_statuses(
a1: 'failed',
a2: 'skipped',
b1: 'skipped',
b2: 'skipped',
c1: 'skipped',
c2: 'skipped'
)
2022-06-21 17:19:12 +05:30
new_a1 = Ci::RetryJobService.new(project, user).clone!(a1)
2022-05-07 20:08:51 +05:30
new_a1.enqueue!
check_jobs_statuses(
a1: 'pending',
a2: 'skipped',
b1: 'skipped',
b2: 'skipped',
c1: 'skipped',
c2: 'skipped'
)
2021-04-29 21:17:54 +05:30
end
2022-05-07 20:08:51 +05:30
it 'marks subsequent skipped jobs as processable' do
execute_after_requeue_service(a1)
check_jobs_statuses(
a1: 'pending',
a2: 'created',
b1: 'created',
b2: 'created',
c1: 'created',
c2: 'created'
)
end
2021-04-29 21:17:54 +05:30
end
2022-05-07 20:08:51 +05:30
2022-10-11 01:57:18 +05:30
context 'with same-stage needs' do
let(:config) do
<<-EOY
a:
script: exit $(($RANDOM % 2))
b:
script: exit 0
needs: [a]
c:
script: exit 0
needs: [b]
EOY
end
let(:pipeline) do
Ci::CreatePipelineService.new(project, user, { ref: 'master' }).execute(:push).payload
end
let(:a) { find_job('a') }
before do
stub_ci_pipeline_yaml_file(config)
check_jobs_statuses(
a: 'pending',
b: 'created',
c: 'created'
)
a.drop!
check_jobs_statuses(
a: 'failed',
b: 'skipped',
c: 'skipped'
)
new_a = Ci::RetryJobService.new(project, user).clone!(a)
new_a.enqueue!
check_jobs_statuses(
a: 'pending',
b: 'skipped',
c: 'skipped'
)
end
it 'marks subsequent skipped jobs as processable' do
execute_after_requeue_service(a)
check_jobs_statuses(
a: 'pending',
b: 'created',
c: 'created'
)
end
end
2022-05-07 20:08:51 +05:30
private
def find_job(name)
processables.find_by!(name: name)
end
def check_jobs_statuses(statuses)
expect(processables.order(:name).pluck(:name, :status)).to contain_exactly(*statuses.stringify_keys.to_a)
end
def processables
pipeline.processables.latest
end
2022-07-23 23:45:48 +05:30
def jobs_name_status_owner_needs
processables.reload.map do |job|
job.attributes.slice('name', 'status', 'user_id').merge('needs' => job.needs.map(&:name))
end
end
2022-05-07 20:08:51 +05:30
def execute_after_requeue_service(processable)
service.execute(processable)
end
2021-04-29 21:17:54 +05:30
end