205 lines
7.0 KiB
Ruby
205 lines
7.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# This shared_example requires the following variables:
|
|
# - `service`, the service which includes AlertManagement::AlertProcessing
|
|
RSpec.shared_examples 'creates an alert management alert or errors' do
|
|
specify do
|
|
expect(subject).to be_success
|
|
expect(subject.payload).to match(alerts: all(a_kind_of(AlertManagement::Alert)))
|
|
end
|
|
|
|
it 'creates AlertManagement::Alert' do
|
|
expect(Gitlab::AppLogger).not_to receive(:warn)
|
|
|
|
expect { subject }.to change(AlertManagement::Alert, :count).by(1)
|
|
end
|
|
|
|
it 'executes the alert service hooks' do
|
|
expect_next_instance_of(AlertManagement::Alert) do |alert|
|
|
expect(alert).to receive(:execute_integrations)
|
|
end
|
|
|
|
subject
|
|
end
|
|
|
|
context 'and fails to save' do
|
|
before do
|
|
allow(AlertManagement::Alert).to receive(:new).and_wrap_original do |m, **args|
|
|
m.call(**args, hosts: ['a' * 256]) # hosts should be 255
|
|
end
|
|
end
|
|
|
|
it_behaves_like 'alerts service responds with an error', :bad_request
|
|
|
|
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_source: source
|
|
)
|
|
|
|
subject
|
|
end
|
|
end
|
|
end
|
|
|
|
RSpec.shared_examples 'handles race condition in alert creation' do
|
|
let(:other_alert) { create(:alert_management_alert, project: project) }
|
|
|
|
context 'when another alert is saved at the same time' do
|
|
before do
|
|
allow_next_instance_of(::AlertManagement::Alert) do |alert|
|
|
allow(alert).to receive(:save) do
|
|
other_alert.update!(fingerprint: alert.fingerprint)
|
|
|
|
raise ActiveRecord::RecordNotUnique
|
|
end
|
|
end
|
|
end
|
|
|
|
it 'finds the other alert and increments the counter' do
|
|
subject
|
|
|
|
expect(other_alert.reload.events).to eq(2)
|
|
end
|
|
end
|
|
|
|
context 'when another alert is saved before the validation runes' do
|
|
before do
|
|
allow_next_instance_of(::AlertManagement::Alert) do |alert|
|
|
allow(alert).to receive(:save).and_wrap_original do |method, *args|
|
|
other_alert.update!(fingerprint: alert.fingerprint)
|
|
|
|
method.call(*args)
|
|
end
|
|
end
|
|
end
|
|
|
|
it 'finds the other alert and increments the counter' do
|
|
subject
|
|
|
|
expect(other_alert.reload.events).to eq(2)
|
|
end
|
|
end
|
|
end
|
|
|
|
# This shared_example requires the following variables:
|
|
# - last_alert_attributes, last created alert
|
|
# - project, project that alert created
|
|
# - payload_raw, hash representation of payload
|
|
# - environment, project's environment
|
|
# - fingerprint, fingerprint hash
|
|
RSpec.shared_examples 'properly assigns the alert properties' do
|
|
specify 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, nil),
|
|
status: AlertManagement::Alert.status_value(:triggered),
|
|
events: 1,
|
|
domain: domain,
|
|
hosts: payload_raw.fetch(:hosts, nil),
|
|
payload: payload_raw.with_indifferent_access,
|
|
issue_id: nil,
|
|
description: payload_raw.fetch(:description, nil),
|
|
monitoring_tool: payload_raw.fetch(:monitoring_tool, nil),
|
|
service: payload_raw.fetch(:service, nil),
|
|
fingerprint: Digest::SHA1.hexdigest(fingerprint),
|
|
environment_id: environment.id,
|
|
ended_at: nil,
|
|
prometheus_alert_id: nil
|
|
}.with_indifferent_access)
|
|
end
|
|
end
|
|
|
|
RSpec.shared_examples 'does not create an alert management alert' do
|
|
specify do
|
|
expect { subject }.not_to change(AlertManagement::Alert, :count)
|
|
end
|
|
end
|
|
|
|
# This shared_example requires the following variables:
|
|
# - `alert`, the alert for which events should be incremented
|
|
RSpec.shared_examples 'adds an alert management alert event' do
|
|
specify do
|
|
expect(alert).not_to receive(:execute_integrations)
|
|
|
|
expect { subject }.to change { alert.reload.events }.by(1)
|
|
|
|
expect(subject).to be_success
|
|
expect(subject.payload).to match(alerts: all(a_kind_of(AlertManagement::Alert)))
|
|
end
|
|
|
|
it_behaves_like 'does not create an alert management alert'
|
|
end
|
|
|
|
# This shared_example requires the following variables:
|
|
# - `alert`, the alert for which events should not be incremented
|
|
RSpec.shared_examples 'does not add an alert management alert event' do
|
|
specify do
|
|
expect { subject }.not_to change { alert.reload.events }
|
|
end
|
|
end
|
|
|
|
RSpec.shared_examples 'processes new firing alert' do
|
|
include_examples 'processes never-before-seen alert'
|
|
|
|
context 'for an existing alert with the same fingerprint' do
|
|
let_it_be(:gitlab_fingerprint) { Digest::SHA1.hexdigest(fingerprint) }
|
|
|
|
context 'which is triggered' do
|
|
let_it_be(:alert) { create(:alert_management_alert, :triggered, fingerprint: gitlab_fingerprint, project: project) }
|
|
|
|
it_behaves_like 'adds an alert management alert event'
|
|
it_behaves_like 'sends alert notification emails if enabled'
|
|
it_behaves_like 'processes incident issues if enabled', with_issue: true
|
|
|
|
it_behaves_like 'does not create an alert management alert'
|
|
it_behaves_like 'does not create a system note for alert'
|
|
|
|
context 'with an existing resolved alert as well' do
|
|
let_it_be(:resolved_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: gitlab_fingerprint) }
|
|
|
|
it_behaves_like 'adds an alert management alert event'
|
|
it_behaves_like 'sends alert notification emails if enabled'
|
|
it_behaves_like 'processes incident issues if enabled', with_issue: true
|
|
|
|
it_behaves_like 'does not create an alert management alert'
|
|
it_behaves_like 'does not create a system note for alert'
|
|
end
|
|
end
|
|
|
|
context 'which is acknowledged' do
|
|
let_it_be(:alert) { create(:alert_management_alert, :acknowledged, fingerprint: gitlab_fingerprint, project: project) }
|
|
|
|
it_behaves_like 'adds an alert management alert event'
|
|
it_behaves_like 'processes incident issues if enabled', with_issue: true
|
|
|
|
it_behaves_like 'does not create an alert management alert'
|
|
it_behaves_like 'does not create a system note for alert'
|
|
it_behaves_like 'does not send alert notification emails'
|
|
end
|
|
|
|
context 'which is ignored' do
|
|
let_it_be(:alert) { create(:alert_management_alert, :ignored, fingerprint: gitlab_fingerprint, project: project) }
|
|
|
|
it_behaves_like 'adds an alert management alert event'
|
|
it_behaves_like 'processes incident issues if enabled', with_issue: true
|
|
|
|
it_behaves_like 'does not create an alert management alert'
|
|
it_behaves_like 'does not create a system note for alert'
|
|
it_behaves_like 'does not send alert notification emails'
|
|
end
|
|
|
|
context 'which is resolved' do
|
|
let_it_be(:alert) { create(:alert_management_alert, :resolved, fingerprint: gitlab_fingerprint, project: project) }
|
|
|
|
include_examples 'processes never-before-seen alert'
|
|
end
|
|
end
|
|
end
|