summaryrefslogtreecommitdiff
path: root/spec/services/projects/alerting/notify_service_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/projects/alerting/notify_service_spec.rb')
-rw-r--r--spec/services/projects/alerting/notify_service_spec.rb258
1 files changed, 63 insertions, 195 deletions
diff --git a/spec/services/projects/alerting/notify_service_spec.rb b/spec/services/projects/alerting/notify_service_spec.rb
index c272ce13132..feae8f3967c 100644
--- a/spec/services/projects/alerting/notify_service_spec.rb
+++ b/spec/services/projects/alerting/notify_service_spec.rb
@@ -3,77 +3,49 @@
require 'spec_helper'
RSpec.describe Projects::Alerting::NotifyService do
- let_it_be_with_reload(:project) { create(:project, :repository) }
+ let_it_be_with_reload(:project) { create(:project) }
+
+ let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
+ let(:payload_raw) { {} }
+
+ let(:service) { described_class.new(project, payload) }
before do
- allow(ProjectServiceWorker).to receive(:perform_async)
+ stub_licensed_features(oncall_schedules: false, generic_alert_fingerprinting: false)
end
describe '#execute' do
- let(:token) { 'invalid-token' }
- let(:starts_at) { Time.current.change(usec: 0) }
- let(:fingerprint) { 'testing' }
- let(:service) { described_class.new(project, payload) }
- let_it_be(:environment) { create(:environment, project: project) }
- let(:environment) { create(:environment, project: project) }
- let(:ended_at) { nil }
- let(:payload_raw) do
- {
- title: 'alert title',
- start_time: starts_at.rfc3339,
- end_time: ended_at&.rfc3339,
- severity: 'low',
- monitoring_tool: 'GitLab RSpec',
- service: 'GitLab Test Suite',
- description: 'Very detailed description',
- hosts: ['1.1.1.1', '2.2.2.2'],
- fingerprint: fingerprint,
- gitlab_environment_name: environment.name
- }.with_indifferent_access
- end
+ include_context 'incident management settings enabled'
- let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
+ subject { service.execute(token, integration) }
- subject { service.execute(token, nil) }
+ context 'with HTTP integration' do
+ let_it_be_with_reload(:integration) { create(:alert_management_http_integration, project: project) }
- shared_examples 'notifications are handled correctly' do
context 'with valid token' do
let(:token) { integration.token }
- let(:incident_management_setting) { double(send_email?: email_enabled, create_issue?: issue_enabled, auto_close_incident?: auto_close_enabled) }
- let(:email_enabled) { false }
- let(:issue_enabled) { false }
- let(:auto_close_enabled) { false }
-
- before do
- allow(service)
- .to receive(:incident_management_setting)
- .and_return(incident_management_setting)
- end
context 'with valid payload' do
- shared_examples 'assigns the alert properties' do
- it 'ensure that created alert has all data properly assigned' do
- subject
- expect(last_alert_attributes).to match(
- project_id: project.id,
- title: payload_raw.fetch(:title),
- started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
- severity: payload_raw.fetch(:severity),
- status: AlertManagement::Alert.status_value(:triggered),
- events: 1,
- domain: 'operations',
- hosts: payload_raw.fetch(:hosts),
- payload: payload_raw.with_indifferent_access,
- issue_id: nil,
- description: payload_raw.fetch(:description),
- monitoring_tool: payload_raw.fetch(:monitoring_tool),
- service: payload_raw.fetch(:service),
- fingerprint: Digest::SHA1.hexdigest(fingerprint),
- environment_id: environment.id,
- ended_at: nil,
- prometheus_alert_id: nil
- )
- end
+ let_it_be(:environment) { create(:environment, project: project) }
+ let_it_be(:fingerprint) { 'testing' }
+ let_it_be(:source) { 'GitLab RSpec' }
+ let_it_be(:starts_at) { Time.current.change(usec: 0) }
+
+ let(:ended_at) { nil }
+ let(:domain) { 'operations' }
+ let(:payload_raw) do
+ {
+ title: 'alert title',
+ start_time: starts_at.rfc3339,
+ end_time: ended_at&.rfc3339,
+ severity: 'low',
+ monitoring_tool: source,
+ service: 'GitLab Test Suite',
+ description: 'Very detailed description',
+ hosts: ['1.1.1.1', '2.2.2.2'],
+ fingerprint: fingerprint,
+ gitlab_environment_name: environment.name
+ }.with_indifferent_access
end
let(:last_alert_attributes) do
@@ -82,8 +54,8 @@ RSpec.describe Projects::Alerting::NotifyService do
.with_indifferent_access
end
- it_behaves_like 'creates an alert management alert'
- it_behaves_like 'assigns the alert properties'
+ it_behaves_like 'processes new firing alert'
+ it_behaves_like 'properly assigns the alert properties'
it 'passes the integration to alert processing' do
expect(Gitlab::AlertManagement::Payload)
@@ -94,101 +66,18 @@ RSpec.describe Projects::Alerting::NotifyService do
subject
end
- it 'creates a system note corresponding to alert creation' do
- expect { subject }.to change(Note, :count).by(1)
- expect(Note.last.note).to include(payload_raw.fetch(:monitoring_tool))
- end
-
- context 'existing alert with same fingerprint' do
- let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
- let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
-
- it_behaves_like 'adds an alert management alert event'
-
- context 'end time given' do
- let(:ended_at) { Time.current.change(nsec: 0) }
-
- it 'does not resolve the alert' do
- expect { subject }.not_to change { alert.reload.status }
- end
-
- it 'does not set the ended at' do
- subject
-
- expect(alert.reload.ended_at).to be_nil
- end
-
- it_behaves_like 'does not an create alert management alert'
- it_behaves_like 'creates single system note based on the source of the alert'
-
- context 'auto_close_enabled setting enabled' do
- let(:auto_close_enabled) { true }
-
- it 'resolves the alert and sets the end time', :aggregate_failures do
- subject
- alert.reload
-
- expect(alert.resolved?).to eq(true)
- expect(alert.ended_at).to eql(ended_at)
- end
-
- it_behaves_like 'creates status-change system note for an auto-resolved alert'
-
- context 'related issue exists' do
- let(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
- let(:issue) { alert.issue }
-
- it { expect { subject }.to change { issue.reload.state }.from('opened').to('closed') }
- it { expect { subject }.to change(ResourceStateEvent, :count).by(1) }
- end
-
- context 'with issue enabled' do
- let(:issue_enabled) { true }
-
- it_behaves_like 'does not process incident issues'
- end
- end
- end
-
- context 'existing alert is resolved' do
- let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint_sha) }
-
- it_behaves_like 'creates an alert management alert'
- it_behaves_like 'assigns the alert properties'
- end
-
- context 'existing alert is ignored' do
- let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: fingerprint_sha) }
-
- it_behaves_like 'adds an alert management alert event'
- end
-
- context 'two existing alerts, one resolved one open' do
- let!(:resolved_existing_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint_sha) }
- let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
-
- it_behaves_like 'adds an alert management alert event'
- end
- end
-
- context 'end time given' do
- let(:ended_at) { Time.current }
-
- it_behaves_like 'creates an alert management alert'
- it_behaves_like 'assigns the alert properties'
- end
-
- context 'with a minimal payload' do
- let(:payload_raw) do
+ context 'with partial payload' do
+ let_it_be(:source) { integration.name }
+ let_it_be(:payload_raw) do
{
title: 'alert title',
start_time: starts_at.rfc3339
}
end
- it_behaves_like 'creates an alert management alert'
+ include_examples 'processes never-before-seen alert'
- it 'created alert has all data properly assigned' do
+ it 'assigns the alert properties' do
subject
expect(last_alert_attributes).to match(
@@ -212,7 +101,19 @@ RSpec.describe Projects::Alerting::NotifyService do
)
end
- it_behaves_like 'creates single system note based on the source of the alert'
+ context 'with existing alert with matching payload' do
+ let_it_be(:fingerprint) { payload_raw.except(:start_time).stringify_keys }
+ let_it_be(:gitlab_fingerprint) { Gitlab::AlertManagement::Fingerprint.generate(fingerprint) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project, fingerprint: gitlab_fingerprint) }
+
+ include_examples 'processes never-before-seen alert'
+ end
+ end
+
+ context 'with resolving payload' do
+ let(:ended_at) { Time.current.change(usec: 0) }
+
+ it_behaves_like 'processes recovery alert'
end
end
@@ -223,63 +124,30 @@ RSpec.describe Projects::Alerting::NotifyService do
allow(Gitlab::Utils::DeepSize).to receive(:new).and_return(deep_size_object)
end
- it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
- it_behaves_like 'does not an create alert management alert'
+ it_behaves_like 'alerts service responds with an error and takes no actions', :bad_request
end
- it_behaves_like 'does not process incident issues'
-
- context 'issue enabled' do
- let(:issue_enabled) { true }
-
- it_behaves_like 'processes incident issues'
-
- context 'when alert already exists' do
- let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
- let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
-
- context 'when existing alert does not have an associated issue' do
- it_behaves_like 'processes incident issues'
- end
-
- context 'when existing alert has an associated issue' do
- let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
-
- it_behaves_like 'does not process incident issues'
- end
+ context 'with inactive integration' do
+ before do
+ integration.update!(active: false)
end
- end
- context 'with emails turned on' do
- let(:email_enabled) { true }
-
- it_behaves_like 'Alert Notification Service sends notification email'
+ it_behaves_like 'alerts service responds with an error and takes no actions', :forbidden
end
end
context 'with invalid token' do
- it_behaves_like 'does not process incident issues due to error', http_status: :unauthorized
- it_behaves_like 'does not an create alert management alert'
- end
- end
-
- context 'with an HTTP Integration' do
- let_it_be_with_reload(:integration) { create(:alert_management_http_integration, project: project) }
+ let(:token) { 'invalid-token' }
- subject { service.execute(token, integration) }
-
- it_behaves_like 'notifications are handled correctly' do
- let(:source) { integration.name }
+ it_behaves_like 'alerts service responds with an error and takes no actions', :unauthorized
end
+ end
- context 'with deactivated HTTP Integration' do
- before do
- integration.update!(active: false)
- end
+ context 'without HTTP integration' do
+ let(:integration) { nil }
+ let(:token) { nil }
- it_behaves_like 'does not process incident issues due to error', http_status: :forbidden
- it_behaves_like 'does not an create alert management alert'
- end
+ it_behaves_like 'alerts service responds with an error and takes no actions', :forbidden
end
end
end