diff options
Diffstat (limited to 'spec/services/alert_management/process_prometheus_alert_service_spec.rb')
-rw-r--r-- | spec/services/alert_management/process_prometheus_alert_service_spec.rb | 146 |
1 files changed, 85 insertions, 61 deletions
diff --git a/spec/services/alert_management/process_prometheus_alert_service_spec.rb b/spec/services/alert_management/process_prometheus_alert_service_spec.rb index 533e2473cb8..b14cc65506a 100644 --- a/spec/services/alert_management/process_prometheus_alert_service_spec.rb +++ b/spec/services/alert_management/process_prometheus_alert_service_spec.rb @@ -3,17 +3,29 @@ require 'spec_helper' RSpec.describe AlertManagement::ProcessPrometheusAlertService do - let_it_be(:project) { create(:project, :repository) } + let_it_be(:project, reload: true) { create(:project, :repository) } before do allow(ProjectServiceWorker).to receive(:perform_async) end describe '#execute' do - subject(:execute) { described_class.new(project, nil, payload).execute } + let(:service) { described_class.new(project, nil, payload) } + let(:incident_management_setting) { double(auto_close_incident?: auto_close_incident, create_issue?: create_issue) } + let(:auto_close_incident) { true } + let(:create_issue) { true } + + before do + allow(service) + .to receive(:incident_management_setting) + .and_return(incident_management_setting) + end + + subject(:execute) { service.execute } context 'when alert payload is valid' do - let(:parsed_alert) { Gitlab::Alerting::Alert.new(project: project, payload: payload) } + let(:parsed_payload) { Gitlab::AlertManagement::Payload.parse(project, payload, monitoring_tool: 'Prometheus') } + let(:fingerprint) { parsed_payload.gitlab_fingerprint } let(:payload) do { 'status' => status, @@ -39,25 +51,26 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do context 'when Prometheus alert status is firing' do context 'when alert with the same fingerprint already exists' do - let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } + let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint) } it_behaves_like 'adds an alert management alert event' + it_behaves_like 'processes incident issues' context 'existing alert is resolved' do - let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } + let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint) } it_behaves_like 'creates an alert management alert' end context 'existing alert is ignored' do - let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } + let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: fingerprint) } it_behaves_like 'adds an alert management alert event' end context 'two existing alerts, one resolved one open' do - let!(:resolved_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } - let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } + let!(:resolved_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint) } + let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint) } it_behaves_like 'adds an alert management alert event' end @@ -78,46 +91,47 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do execute end end + + context 'when auto-alert creation is disabled' do + let(:create_issue) { false } + + it_behaves_like 'does not process incident issues' + end end context 'when alert does not exist' do context 'when alert can be created' do it_behaves_like 'creates an alert management alert' - it 'processes the incident alert' do - expect(IncidentManagement::ProcessAlertWorker) - .to receive(:perform_async) - .with(nil, nil, kind_of(Integer)) - .once + it 'creates a system note corresponding to alert creation' do + expect { subject }.to change(Note, :count).by(1) + end + + it_behaves_like 'processes incident issues' - expect(subject).to be_success + context 'when auto-alert creation is disabled' do + let(:create_issue) { false } + + it_behaves_like 'does not process incident issues' end end context 'when alert cannot be created' do - let(:errors) { double(messages: { hosts: ['hosts array is over 255 chars'] })} - let(:am_alert) { instance_double(AlertManagement::Alert, save: false, errors: errors) } - before do - allow(AlertManagement::Alert).to receive(:new).and_return(am_alert) + payload['annotations']['title'] = 'description' * 50 end it 'writes a warning to the log' do expect(Gitlab::AppLogger).to receive(:warn).with( message: 'Unable to create AlertManagement::Alert', project_id: project.id, - alert_errors: { hosts: ['hosts array is over 255 chars'] } + alert_errors: { title: ["is too long (maximum is 200 characters)"] } ) execute end - it 'does not create incident issue' do - expect(IncidentManagement::ProcessAlertWorker) - .not_to receive(:perform_async) - - expect(subject).to be_success - end + it_behaves_like 'does not process incident issues' end it { is_expected.to be_success } @@ -126,57 +140,67 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do context 'when Prometheus alert status is resolved' do let(:status) { 'resolved' } - let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } + let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint) } - context 'when status can be changed' do - it 'resolves an existing alert' do - expect { execute }.to change { alert.reload.resolved? }.to(true) - end + context 'when auto_resolve_incident set to true' do + context 'when status can be changed' do + it 'resolves an existing alert' do + expect { execute }.to change { alert.reload.resolved? }.to(true) + end - [true, false].each do |state_tracking_enabled| - context 'existing issue' do - before do - stub_feature_flags(track_resource_state_change_events: state_tracking_enabled) - end + [true, false].each do |state_tracking_enabled| + context 'existing issue' do + before do + stub_feature_flags(track_resource_state_change_events: state_tracking_enabled) + end - let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: parsed_alert.gitlab_fingerprint) } + let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint) } - it 'closes the issue' do - issue = alert.issue + it 'closes the issue' do + issue = alert.issue - expect { execute } - .to change { issue.reload.state } - .from('opened') - .to('closed') - end + expect { execute } + .to change { issue.reload.state } + .from('opened') + .to('closed') + end - if state_tracking_enabled - specify { expect { execute }.to change(ResourceStateEvent, :count).by(1) } - else - specify { expect { execute }.to change(Note, :count).by(1) } + if state_tracking_enabled + specify { expect { execute }.to change(ResourceStateEvent, :count).by(1) } + else + specify { expect { execute }.to change(Note, :count).by(1) } + end end end end - end - context 'when status change did not succeed' do - before do - allow(AlertManagement::Alert).to receive(:for_fingerprint).and_return([alert]) - allow(alert).to receive(:resolve).and_return(false) - end + context 'when status change did not succeed' do + before do + allow(AlertManagement::Alert).to receive(:for_fingerprint).and_return([alert]) + allow(alert).to receive(:resolve).and_return(false) + end - it 'writes a warning to the log' do - expect(Gitlab::AppLogger).to receive(:warn).with( - message: 'Unable to update AlertManagement::Alert status to resolved', - project_id: project.id, - alert_id: alert.id - ) + it 'writes a warning to the log' do + expect(Gitlab::AppLogger).to receive(:warn).with( + message: 'Unable to update AlertManagement::Alert status to resolved', + project_id: project.id, + alert_id: alert.id + ) - execute + execute + end end + + it { is_expected.to be_success } end - it { is_expected.to be_success } + context 'when auto_resolve_incident set to false' do + let(:auto_close_incident) { false } + + it 'does not resolve an existing alert' do + expect { execute }.not_to change { alert.reload.resolved? } + end + end end context 'environment given' do |