retry_pipeline_service_spec.rb 3.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
require 'spec_helper'

describe Ci::RetryPipelineService, '#execute', :services do
  let(:user) { create(:user) }
  let(:project) { create(:empty_project) }
  let(:pipeline) { create(:ci_pipeline, project: project) }
  let(:service) { described_class.new(pipeline, user) }

  context 'when user has ability to modify pipeline' do
    let(:user) { create(:admin) }

    context 'when there are failed builds in the last stage' do
      before do
        create_build(name: 'rspec 1', status: :success, stage_num: 0)
        create_build(name: 'rspec 2', status: :failed, stage_num: 1)
        create_build(name: 'rspec 3', status: :canceled, stage_num: 1)
      end

      it 'enqueues all builds in the last stage' do
        service.execute

        expect(build('rspec 2')).to be_pending
        expect(build('rspec 3')).to be_pending
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
        expect(pipeline.reload).to be_running
      end
    end

    context 'when there are failed or canceled builds in the first stage' do
      before do
        create_build(name: 'rspec 1', status: :failed, stage_num: 0)
        create_build(name: 'rspec 2', status: :canceled, stage_num: 0)
        create_build(name: 'rspec 3', status: :skipped, stage_num: 1)
        create_build(name: 'deploy 1', status: :skipped, stage_num: 2)
      end

      it 'retries builds failed builds and marks subsequent for processing' do
        service.execute

        expect(build('rspec 1')).to be_pending
        expect(build('rspec 2')).to be_pending
        expect(build('rspec 3')).to be_created
        expect(build('deploy 1')).to be_created
        expect(pipeline.reload).to be_running
      end
    end

    context 'when there is failed build present which was run on failure' do
      before do
        create_build(name: 'rspec 1', status: :failed, stage_num: 0)
        create_build(name: 'rspec 2', status: :canceled, stage_num: 0)
        create_build(name: 'rspec 3', status: :skipped, stage_num: 1)
        create_build(name: 'report 1', status: :failed, stage_num: 2)
      end

      it 'retries builds failed builds and marks subsequent for processing' do
        service.execute

        expect(build('rspec 1')).to be_pending
        expect(build('rspec 2')).to be_pending
        expect(build('rspec 3')).to be_created
        expect(build('report 1')).to be_created
        expect(pipeline.reload).to be_running
      end

      it 'creates a new job for report job in this case' do
        service.execute

        expect(statuses.where(name: 'report 1').count).to eq 2
69 70 71 72 73 74 75 76 77 78 79
      end
    end
  end

  context 'when user is not allowed to retry pipeline' do
    it 'raises an error' do
      expect { service.execute }
        .to raise_error Gitlab::Access::AccessDeniedError
    end
  end

80 81 82 83
  def statuses
    pipeline.reload.statuses
  end

84
  def build(name)
85
    statuses.latest.find_by(name: name)
86 87 88 89 90 91 92 93 94 95 96 97
  end

  def create_build(name:, status:, stage_num:)
    create(:ci_build, name: name,
                      status: status,
                      stage: "stage_#{stage_num}",
                      stage_idx: stage_num,
                      pipeline: pipeline) do |build|
      pipeline.update_status
    end
  end
end