diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-18 14:18:50 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-18 14:18:50 +0300 |
commit | 8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch) | |
tree | a77e7fe7a93de11213032ed4ab1f33a3db51b738 /spec/services/projects/prometheus/alerts | |
parent | 00b35af3db1abfe813a778f643dad221aad51fca (diff) |
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'spec/services/projects/prometheus/alerts')
-rw-r--r-- | spec/services/projects/prometheus/alerts/create_events_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/projects/prometheus/alerts/notify_service_spec.rb | 146 |
2 files changed, 82 insertions, 66 deletions
diff --git a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb index 35f23afd7a2..61236b5bbdb 100644 --- a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb +++ b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb @@ -89,9 +89,9 @@ describe Projects::Prometheus::Alerts::CreateEventsService do context 'with a resolved payload' do let(:started_at) { truncate_to_second(Time.current) } let(:ended_at) { started_at + 1 } - let(:payload_key) { PrometheusAlertEvent.payload_key_for(alert.prometheus_metric_id, utc_rfc3339(started_at)) } let(:resolved_event) { alert_payload(status: 'resolved', started_at: started_at, ended_at: ended_at) } let(:alerts_payload) { { 'alerts' => [resolved_event] } } + let(:payload_key) { Gitlab::Alerting::Alert.new(project: project, payload: resolved_event).gitlab_fingerprint } context 'with a matching firing event' do before do diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb index 009543f9016..95acedb1e76 100644 --- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb +++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Projects::Prometheus::Alerts::NotifyService do + include PrometheusHelpers + let_it_be(:project, reload: true) { create(:project) } let(:service) { described_class.new(project, nil, payload) } @@ -92,9 +94,10 @@ describe Projects::Prometheus::Alerts::NotifyService do end context 'with valid payload' do - let(:alert_firing) { create(:prometheus_alert, project: project) } - let(:alert_resolved) { create(:prometheus_alert, project: project) } - let(:payload_raw) { payload_for(firing: [alert_firing], resolved: [alert_resolved]) } + let_it_be(:alert_firing) { create(:prometheus_alert, project: project) } + let_it_be(:alert_resolved) { create(:prometheus_alert, project: project) } + let_it_be(:cluster) { create(:cluster, :provided_by_user, projects: [project]) } + let(:payload_raw) { prometheus_alert_payload(firing: [alert_firing], resolved: [alert_resolved]) } let(:payload) { ActionController::Parameters.new(payload_raw).permit! } let(:payload_alert_firing) { payload_raw['alerts'].first } let(:token) { 'token' } @@ -116,9 +119,7 @@ describe Projects::Prometheus::Alerts::NotifyService do with_them do before do - cluster = create(:cluster, :provided_by_user, - projects: [project], - enabled: cluster_enabled) + cluster.update!(enabled: cluster_enabled) if status create(:clusters_applications_prometheus, status, @@ -179,6 +180,39 @@ describe Projects::Prometheus::Alerts::NotifyService do end end + context 'with generic alerts integration' do + using RSpec::Parameterized::TableSyntax + + where(:alerts_service, :token, :result) do + :active | :valid | :success + :active | :invalid | :failure + :active | nil | :failure + :inactive | :valid | :failure + nil | nil | :failure + end + + with_them do + let(:valid) { project.alerts_service.token } + let(:invalid) { 'invalid token' } + let(:token_input) { public_send(token) if token } + + before do + if alerts_service + create(:alerts_service, alerts_service, project: project) + end + end + + case result = params[:result] + when :success + it_behaves_like 'notifies alerts' + when :failure + it_behaves_like 'no notifications', http_status: :unauthorized + else + raise "invalid result: #{result.inspect}" + end + end + end + context 'alert emails' do before do create(:prometheus_service, project: project) @@ -227,7 +261,7 @@ describe Projects::Prometheus::Alerts::NotifyService do context 'with multiple firing alerts and resolving alerts' do let(:payload_raw) do - payload_for(firing: [alert_firing, alert_firing], resolved: [alert_resolved]) + prometheus_alert_payload(firing: [alert_firing, alert_firing], resolved: [alert_resolved]) end it 'processes Prometheus alerts' do @@ -258,7 +292,7 @@ describe Projects::Prometheus::Alerts::NotifyService do context 'multiple firing alerts' do let(:payload_raw) do - payload_for(firing: [alert_firing, alert_firing], resolved: []) + prometheus_alert_payload(firing: [alert_firing, alert_firing], resolved: []) end it_behaves_like 'processes incident issues', 2 @@ -266,7 +300,7 @@ describe Projects::Prometheus::Alerts::NotifyService do context 'without firing alerts' do let(:payload_raw) do - payload_for(firing: [], resolved: [alert_resolved]) + prometheus_alert_payload(firing: [], resolved: [alert_resolved]) end it_behaves_like 'processes incident issues', 1 @@ -284,24 +318,17 @@ describe Projects::Prometheus::Alerts::NotifyService do end context 'with invalid payload' do - context 'without version' do + context 'when payload is not processable' do let(:payload) { {} } - it_behaves_like 'no notifications', http_status: :unprocessable_entity - end - - context 'when version is not "4"' do - let(:payload) { { 'version' => '5' } } + before do + allow(described_class).to receive(:processable?).with(payload) + .and_return(false) + end it_behaves_like 'no notifications', http_status: :unprocessable_entity end - context 'with missing alerts' do - let(:payload) { { 'version' => '4' } } - - it_behaves_like 'no notifications', http_status: :unauthorized - end - context 'when the payload is too big' do let(:payload) { { 'the-payload-is-too-big' => true } } let(:deep_size_object) { instance_double(Gitlab::Utils::DeepSize, valid?: false) } @@ -328,50 +355,39 @@ describe Projects::Prometheus::Alerts::NotifyService do end end - private - - def payload_for(firing: [], resolved: []) - status = firing.any? ? 'firing' : 'resolved' - alerts = firing + resolved - alert_name = alerts.first.title - prometheus_metric_id = alerts.first.prometheus_metric_id.to_s - - alerts_map = \ - firing.map { |alert| map_alert_payload('firing', alert) } + - resolved.map { |alert| map_alert_payload('resolved', alert) } - - # See https://prometheus.io/docs/alerting/configuration/#%3Cwebhook_config%3E - { - 'version' => '4', - 'receiver' => 'gitlab', - 'status' => status, - 'alerts' => alerts_map, - 'groupLabels' => { - 'alertname' => alert_name - }, - 'commonLabels' => { - 'alertname' => alert_name, - 'gitlab' => 'hook', - 'gitlab_alert_id' => prometheus_metric_id - }, - 'commonAnnotations' => {}, - 'externalURL' => '', - 'groupKey' => "{}:{alertname=\'#{alert_name}\'}" - } - end + describe '.processable?' do + let(:valid_payload) { prometheus_alert_payload } + + subject { described_class.processable?(payload) } + + context 'with valid payload' do + let(:payload) { valid_payload } + + it { is_expected.to eq(true) } + + context 'containing unrelated keys' do + let(:payload) { valid_payload.merge('unrelated' => 'key') } - def map_alert_payload(status, alert) - { - 'status' => status, - 'labels' => { - 'alertname' => alert.title, - 'gitlab' => 'hook', - 'gitlab_alert_id' => alert.prometheus_metric_id.to_s - }, - 'annotations' => {}, - 'startsAt' => '2018-09-24T08:57:31.095725221Z', - 'endsAt' => '0001-01-01T00:00:00Z', - 'generatorURL' => 'http://prometheus-prometheus-server-URL' - } + it { is_expected.to eq(true) } + end + end + + context 'with invalid payload' do + where(:missing_key) do + described_class::REQUIRED_PAYLOAD_KEYS.to_a + end + + with_them do + let(:payload) { valid_payload.except(missing_key) } + + it { is_expected.to eq(false) } + end + end + + context 'with unsupported version' do + let(:payload) { valid_payload.merge('version' => '5') } + + it { is_expected.to eq(false) } + end end end |