cluster_update_app_worker_spec.rb 3.57 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5
require 'spec_helper'

describe ClusterUpdateAppWorker do
6 7 8 9
  include ExclusiveLeaseHelpers

  let_it_be(:project) { create(:project) }

10 11 12 13 14
  let(:prometheus_update_service) { spy }

  subject { described_class.new }

  around do |example|
Sean Arnold's avatar
Sean Arnold committed
15
    Timecop.freeze(Time.current) { example.run }
16 17 18 19 20 21 22 23 24
  end

  before do
    allow(::Clusters::Applications::PrometheusUpdateService).to receive(:new).and_return(prometheus_update_service)
  end

  describe '#perform' do
    context 'when the application last_update_started_at is higher than the time the job was scheduled in' do
      it 'does nothing' do
Sean Arnold's avatar
Sean Arnold committed
25
        application = create(:clusters_applications_prometheus, :updated, last_update_started_at: Time.current)
26 27 28

        expect(prometheus_update_service).not_to receive(:execute)

Sean Arnold's avatar
Sean Arnold committed
29
        expect(subject.perform(application.name, application.id, project.id, Time.current - 5.minutes)).to be_nil
30 31 32 33
      end
    end

    context 'when another worker is already running' do
Tiago Botelho's avatar
Tiago Botelho committed
34
      it 'returns nil' do
35 36
        application = create(:clusters_applications_prometheus, :updating)

Sean Arnold's avatar
Sean Arnold committed
37
        expect(subject.perform(application.name, application.id, project.id, Time.current)).to be_nil
38 39 40 41 42 43 44 45
      end
    end

    it 'executes PrometheusUpdateService' do
      application = create(:clusters_applications_prometheus, :installed)

      expect(prometheus_update_service).to receive(:execute)

Sean Arnold's avatar
Sean Arnold committed
46
      subject.perform(application.name, application.id, project.id, Time.current)
47
    end
48 49

    context 'with exclusive lease' do
50
      let_it_be(:user) { create(:user) }
51 52 53 54
      let(:application) { create(:clusters_applications_prometheus, :installed) }
      let(:lease_key) { "#{described_class.name.underscore}-#{application.id}" }

      before do
55 56
        # update_highest_role uses exclusive key too:
        allow(Gitlab::ExclusiveLease).to receive(:new).and_call_original
57 58 59 60 61 62
        stub_exclusive_lease_taken(lease_key)
      end

      it 'does not allow same app to be updated concurrently by same project' do
        expect(Clusters::Applications::PrometheusUpdateService).not_to receive(:new)

Sean Arnold's avatar
Sean Arnold committed
63
        subject.perform(application.name, application.id, project.id, Time.current)
64 65
      end

66 67
      it 'does not allow same app to be updated concurrently by different project', :aggregate_failures do
        project1 = create(:project, namespace: create(:namespace, owner: user))
68 69 70

        expect(Clusters::Applications::PrometheusUpdateService).not_to receive(:new)

Sean Arnold's avatar
Sean Arnold committed
71
        subject.perform(application.name, application.id, project1.id, Time.current)
72 73 74 75 76 77 78 79 80 81 82
      end

      it 'allows different app to be updated concurrently by same project' do
        application2 = create(:clusters_applications_prometheus, :installed)
        lease_key2 = "#{described_class.name.underscore}-#{application2.id}"

        stub_exclusive_lease(lease_key2)

        expect(Clusters::Applications::PrometheusUpdateService).to receive(:new)
          .with(application2, project)

Sean Arnold's avatar
Sean Arnold committed
83
        subject.perform(application2.name, application2.id, project.id, Time.current)
84 85
      end

86
      it 'allows different app to be updated by different project', :aggregate_failures do
87 88
        application2 = create(:clusters_applications_prometheus, :installed)
        lease_key2 = "#{described_class.name.underscore}-#{application2.id}"
89 90

        project2 = create(:project, namespace: create(:namespace, owner: user))
91 92 93 94 95 96

        stub_exclusive_lease(lease_key2)

        expect(Clusters::Applications::PrometheusUpdateService).to receive(:new)
          .with(application2, project2)

Sean Arnold's avatar
Sean Arnold committed
97
        subject.perform(application2.name, application2.id, project2.id, Time.current)
98 99
      end
    end
100 101
  end
end