BigW Consortium Gitlab

stuck_ci_jobs_worker_spec.rb 3.61 KB
Newer Older
1
require 'spec_helper'
2

3
describe StuckCiJobsWorker do
4
  let!(:runner) { create :ci_runner }
5
  let!(:job) { create :ci_build, runner: runner }
6
  let(:worker) { described_class.new }
Tomasz Maczukin committed
7
  let(:exclusive_lease_uuid) { SecureRandom.uuid }
8 9

  subject do
10 11
    job.reload
    job.status
12 13
  end

14
  before do
15
    job.update!(status: status, updated_at: updated_at)
Tomasz Maczukin committed
16
    allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).and_return(exclusive_lease_uuid)
17
  end
18

19
  shared_examples 'job is dropped' do
20 21 22 23 24 25
    it 'changes status' do
      worker.perform
      is_expected.to eq('failed')
    end
  end

26
  shared_examples 'job is unchanged' do
27 28 29 30 31 32
    it "doesn't change status" do
      worker.perform
      is_expected.to eq(status)
    end
  end

33
  context 'when job is pending' do
34 35
    let(:status) { 'pending' }

36
    context 'when job is not stuck' do
37 38 39
      before do
        allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(false)
      end
40

41
      context 'when job was not updated for more than 1 day ago' do
42
        let(:updated_at) { 2.days.ago }
43
        it_behaves_like 'job is dropped'
44 45
      end

46
      context 'when job was updated in less than 1 day ago' do
47
        let(:updated_at) { 6.hours.ago }
48
        it_behaves_like 'job is unchanged'
49 50
      end

51
      context 'when job was not updated for more than 1 hour ago' do
52
        let(:updated_at) { 2.hours.ago }
53
        it_behaves_like 'job is unchanged'
54 55 56
      end
    end

57
    context 'when job is stuck' do
58 59 60
      before do
        allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(true)
      end
61

62
      context 'when job was not updated for more than 1 hour ago' do
63
        let(:updated_at) { 2.hours.ago }
64
        it_behaves_like 'job is dropped'
65 66
      end

67
      context 'when job was updated in less than 1 hour ago' do
68
        let(:updated_at) { 30.minutes.ago }
69
        it_behaves_like 'job is unchanged'
70 71 72
      end
    end
  end
73

74
  context 'when job is running' do
75 76
    let(:status) { 'running' }

77
    context 'when job was not updated for more than 1 hour ago' do
78
      let(:updated_at) { 2.hours.ago }
79
      it_behaves_like 'job is dropped'
80 81
    end

82
    context 'when job was updated in less than 1 hour ago' do
83
      let(:updated_at) { 30.minutes.ago }
84
      it_behaves_like 'job is unchanged'
85 86 87 88
    end
  end

  %w(success skipped failed canceled).each do |status|
89
    context "when job is #{status}" do
90 91
      let(:status) { status }
      let(:updated_at) { 2.days.ago }
92
      it_behaves_like 'job is unchanged'
93 94 95 96 97 98 99
    end
  end

  context 'for deleted project' do
    let(:status) { 'running' }
    let(:updated_at) { 2.days.ago }

100 101 102
    before do
      job.project.update(pending_delete: true)
    end
103

104
    it 'does not drop job' do
105 106 107 108
      expect_any_instance_of(Ci::Build).not_to receive(:drop)
      worker.perform
    end
  end
109 110 111 112

  describe 'exclusive lease' do
    let(:status) { 'running' }
    let(:updated_at) { 2.days.ago }
Tomasz Maczukin committed
113
    let(:worker2) { described_class.new }
114

Tomasz Maczukin committed
115 116 117
    it 'is guard by exclusive lease when executed concurrently' do
      expect(worker).to receive(:drop).at_least(:once)
      expect(worker2).not_to receive(:drop)
118 119
      worker.perform
      allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).and_return(false)
Tomasz Maczukin committed
120 121 122 123 124 125 126 127 128 129 130 131
      worker2.perform
    end

    it 'can be executed in sequence' do
      expect(worker).to receive(:drop).at_least(:once)
      expect(worker2).to receive(:drop).at_least(:once)
      worker.perform
      worker2.perform
    end

    it 'cancels exclusive lease after worker perform' do
      expect(Gitlab::ExclusiveLease).to receive(:cancel).with(described_class::EXCLUSIVE_LEASE_KEY, exclusive_lease_uuid)
132 133 134
      worker.perform
    end
  end
Tomasz Maczukin committed
135
end