diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 15:26:25 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 15:26:25 +0300 |
commit | a09983ae35713f5a2bbb100981116d31ce99826e (patch) | |
tree | 2ee2af7bd104d57086db360a7e6d8c9d5d43667a /spec/services/projects/prometheus/alerts | |
parent | 18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff) |
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'spec/services/projects/prometheus/alerts')
5 files changed, 39 insertions, 406 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 deleted file mode 100644 index 61236b5bbdb..00000000000 --- a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb +++ /dev/null @@ -1,312 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Projects::Prometheus::Alerts::CreateEventsService do - let(:user) { create(:user) } - let_it_be(:project) { create(:project) } - let(:metric) { create(:prometheus_metric, project: project) } - let(:service) { described_class.new(project, user, alerts_payload) } - - shared_examples 'events persisted' do |expected_count| - subject { service.execute } - - it 'returns proper amount of created events' do - expect(subject.size).to eq(expected_count) - end - - it 'increments event count' do - expect { subject }.to change { PrometheusAlertEvent.count }.to(expected_count) - end - end - - shared_examples 'no events persisted' do - subject { service.execute } - - it 'returns no created events' do - expect(subject).to be_empty - end - - it 'does not change event count' do - expect { subject }.not_to change { PrometheusAlertEvent.count } - end - end - - shared_examples 'self managed events persisted' do - subject { service.execute } - - it 'returns created events' do - expect(subject).not_to be_empty - end - - it 'does change self managed event count' do - expect { subject }.to change { SelfManagedPrometheusAlertEvent.count } - end - end - - context 'with valid alerts_payload' do - let!(:alert) { create(:prometheus_alert, prometheus_metric: metric, project: project) } - - let(:events) { service.execute } - - context 'with a firing payload' do - let(:started_at) { truncate_to_second(Time.current) } - let(:firing_event) { alert_payload(status: 'firing', started_at: started_at) } - let(:alerts_payload) { { 'alerts' => [firing_event] } } - - it_behaves_like 'events persisted', 1 - - it 'returns created event' do - event = events.first - - expect(event).to be_firing - expect(event.started_at).to eq(started_at) - expect(event.ended_at).to be_nil - end - - context 'with 2 different firing events' do - let(:another_firing_event) { alert_payload(status: 'firing', started_at: started_at + 1) } - let(:alerts_payload) { { 'alerts' => [firing_event, another_firing_event] } } - - it_behaves_like 'events persisted', 2 - end - - context 'with already persisted firing event' do - before do - service.execute - end - - it_behaves_like 'no events persisted' - end - - context 'with duplicate payload' do - let(:alerts_payload) { { 'alerts' => [firing_event, firing_event] } } - - it_behaves_like 'events persisted', 1 - end - end - - context 'with a resolved payload' do - let(:started_at) { truncate_to_second(Time.current) } - let(:ended_at) { started_at + 1 } - 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 - create(:prometheus_alert_event, - prometheus_alert: alert, - payload_key: payload_key, - started_at: started_at) - end - - it 'does not create an additional event' do - expect { service.execute }.not_to change { PrometheusAlertEvent.count } - end - - it 'marks firing event as `resolved`' do - expect(events.size).to eq(1) - - event = events.first - expect(event).to be_resolved - expect(event.started_at).to eq(started_at) - expect(event.ended_at).to eq(ended_at) - end - - context 'with duplicate payload' do - let(:alerts_payload) { { 'alerts' => [resolved_event, resolved_event] } } - - it 'does not create an additional event' do - expect { service.execute }.not_to change { PrometheusAlertEvent.count } - end - - it 'marks firing event as `resolved` only once' do - expect(events.size).to eq(1) - end - end - end - - context 'without a matching firing event' do - context 'due to payload_key' do - let(:payload_key) { 'some other payload_key' } - - before do - create(:prometheus_alert_event, - prometheus_alert: alert, - payload_key: payload_key, - started_at: started_at) - end - - it_behaves_like 'no events persisted' - end - - context 'due to status' do - before do - create(:prometheus_alert_event, :resolved, - prometheus_alert: alert, - started_at: started_at) - end - - it_behaves_like 'no events persisted' - end - end - - context 'with already resolved event' do - before do - service.execute - end - - it_behaves_like 'no events persisted' - end - end - - context 'with a metric from another project' do - let(:another_project) { create(:project) } - let(:metric) { create(:prometheus_metric, project: another_project) } - let(:alerts_payload) { { 'alerts' => [alert_payload] } } - - let!(:alert) do - create(:prometheus_alert, - prometheus_metric: metric, - project: another_project) - end - - it_behaves_like 'no events persisted' - end - end - - context 'with invalid payload' do - let(:alert) { create(:prometheus_alert, prometheus_metric: metric, project: project) } - - describe '`alerts` key' do - context 'is missing' do - let(:alerts_payload) { {} } - - it_behaves_like 'no events persisted' - end - - context 'is nil' do - let(:alerts_payload) { { 'alerts' => nil } } - - it_behaves_like 'no events persisted' - end - - context 'is empty' do - let(:alerts_payload) { { 'alerts' => [] } } - - it_behaves_like 'no events persisted' - end - - context 'is not a Hash' do - let(:alerts_payload) { { 'alerts' => [:not_a_hash] } } - - it_behaves_like 'no events persisted' - end - - describe '`status`' do - context 'is missing' do - let(:alerts_payload) { { 'alerts' => [alert_payload(status: nil)] } } - - it_behaves_like 'no events persisted' - end - - context 'is invalid' do - let(:alerts_payload) { { 'alerts' => [alert_payload(status: 'invalid')] } } - - it_behaves_like 'no events persisted' - end - end - - describe '`started_at`' do - context 'is missing' do - let(:alerts_payload) { { 'alerts' => [alert_payload(started_at: nil)] } } - - it_behaves_like 'no events persisted' - end - - context 'is invalid' do - let(:alerts_payload) { { 'alerts' => [alert_payload(started_at: 'invalid date')] } } - - it_behaves_like 'no events persisted' - end - end - - describe '`ended_at`' do - context 'is missing and status is resolved' do - let(:alerts_payload) { { 'alerts' => [alert_payload(ended_at: nil, status: 'resolved')] } } - - it_behaves_like 'no events persisted' - end - - context 'is invalid and status is resolved' do - let(:alerts_payload) { { 'alerts' => [alert_payload(ended_at: 'invalid date', status: 'resolved')] } } - - it_behaves_like 'no events persisted' - end - end - - describe '`labels`' do - describe '`gitlab_alert_id`' do - context 'is missing' do - let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: nil)] } } - - it_behaves_like 'no events persisted' - end - - context 'is missing but title is given' do - let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: nil, title: 'alert')] } } - - it_behaves_like 'self managed events persisted' - end - - context 'is missing and environment name is given' do - let(:environment) { create(:environment, project: project) } - let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: nil, title: 'alert', environment: environment.name)] } } - - it_behaves_like 'self managed events persisted' - - it 'associates the environment to the alert event' do - service.execute - - expect(SelfManagedPrometheusAlertEvent.last.environment).to eq environment - end - end - - context 'is invalid' do - let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: '-1')] } } - - it_behaves_like 'no events persisted' - end - end - end - end - end - - private - - def alert_payload(status: 'firing', started_at: Time.current, ended_at: Time.current, gitlab_alert_id: alert.prometheus_metric_id, title: nil, environment: nil) - payload = {} - - payload['status'] = status if status - payload['startsAt'] = utc_rfc3339(started_at) if started_at - payload['endsAt'] = utc_rfc3339(ended_at) if ended_at - payload['labels'] = {} - payload['labels']['gitlab_alert_id'] = gitlab_alert_id.to_s if gitlab_alert_id - payload['labels']['alertname'] = title if title - payload['labels']['gitlab_environment_name'] = environment if environment - - payload - end - - # Example: 2018-09-27T18:25:31.079079416Z - def utc_rfc3339(date) - date.utc.rfc3339 - rescue - date - end - - def truncate_to_second(date) - date.change(usec: 0) - end -end diff --git a/spec/services/projects/prometheus/alerts/create_service_spec.rb b/spec/services/projects/prometheus/alerts/create_service_spec.rb index 50c776df734..c0bc9336558 100644 --- a/spec/services/projects/prometheus/alerts/create_service_spec.rb +++ b/spec/services/projects/prometheus/alerts/create_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Projects::Prometheus::Alerts::CreateService do +RSpec.describe Projects::Prometheus::Alerts::CreateService do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } diff --git a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb index 7205ace8308..573711051b7 100644 --- a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb +++ b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Projects::Prometheus::Alerts::DestroyService do +RSpec.describe Projects::Prometheus::Alerts::DestroyService do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } let_it_be(:alert) { create(:prometheus_alert, project: project) } diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb index 95acedb1e76..aae257e3e3a 100644 --- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb +++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Projects::Prometheus::Alerts::NotifyService do +RSpec.describe Projects::Prometheus::Alerts::NotifyService do include PrometheusHelpers let_it_be(:project, reload: true) { create(:project) } @@ -36,48 +36,8 @@ describe Projects::Prometheus::Alerts::NotifyService do end end - shared_examples 'processes incident issues' do |amount| - let(:create_incident_service) { spy } - - it 'processes issues' do - expect(IncidentManagement::ProcessPrometheusAlertWorker) - .to receive(:perform_async) - .with(project.id, kind_of(Hash)) - .exactly(amount).times - - Sidekiq::Testing.inline! do - expect(subject).to be_success - end - end - end - - shared_examples 'does not process incident issues' do - it 'does not process issues' do - expect(IncidentManagement::ProcessPrometheusAlertWorker) - .not_to receive(:perform_async) - - expect(subject).to be_success - end - end - - shared_examples 'persists events' do - let(:create_events_service) { spy } - - it 'persists events' do - expect(Projects::Prometheus::Alerts::CreateEventsService) - .to receive(:new) - .and_return(create_events_service) - - expect(create_events_service) - .to receive(:execute) - - expect(subject).to be_success - end - end - shared_examples 'notifies alerts' do it_behaves_like 'sends notification email' - it_behaves_like 'persists events' end shared_examples 'no notifications' do |http_status:| @@ -102,6 +62,41 @@ describe Projects::Prometheus::Alerts::NotifyService do let(:payload_alert_firing) { payload_raw['alerts'].first } let(:token) { 'token' } + context 'with environment specific clusters' do + let(:prd_cluster) do + cluster + end + + let(:stg_cluster) do + create(:cluster, :provided_by_user, projects: [project], enabled: true, environment_scope: 'stg/*') + end + + let(:stg_environment) do + create(:environment, project: project, name: 'stg/1') + end + + let(:alert_firing) do + create(:prometheus_alert, project: project, environment: stg_environment) + end + + before do + create(:clusters_applications_prometheus, :installed, + cluster: prd_cluster, alert_manager_token: token) + create(:clusters_applications_prometheus, :installed, + cluster: stg_cluster, alert_manager_token: nil) + end + + context 'without token' do + let(:token_input) { nil } + + it_behaves_like 'notifies alerts' + end + + context 'with token' do + it_behaves_like 'no notifications', http_status: :unauthorized + end + end + context 'with project specific cluster' do using RSpec::Parameterized::TableSyntax @@ -222,8 +217,6 @@ describe Projects::Prometheus::Alerts::NotifyService do context 'when incident_management_setting does not exist' do let!(:setting) { nil } - it_behaves_like 'persists events' - it 'does not send notification email', :sidekiq_might_not_need_inline do expect_any_instance_of(NotificationService) .not_to receive(:async) @@ -241,8 +234,6 @@ describe Projects::Prometheus::Alerts::NotifyService do create(:project_incident_management_setting, send_email: false, project: project) end - it_behaves_like 'persists events' - it 'does not send notification' do expect(NotificationService).not_to receive(:new) @@ -276,45 +267,6 @@ describe Projects::Prometheus::Alerts::NotifyService do end end end - - context 'process incident issues' do - before do - create(:prometheus_service, project: project) - create(:project_alerting_setting, project: project, token: token) - end - - context 'with create_issue setting enabled' do - before do - setting.update!(create_issue: true) - end - - it_behaves_like 'processes incident issues', 2 - - context 'multiple firing alerts' do - let(:payload_raw) do - prometheus_alert_payload(firing: [alert_firing, alert_firing], resolved: []) - end - - it_behaves_like 'processes incident issues', 2 - end - - context 'without firing alerts' do - let(:payload_raw) do - prometheus_alert_payload(firing: [], resolved: [alert_resolved]) - end - - it_behaves_like 'processes incident issues', 1 - end - end - - context 'with create_issue setting disabled' do - before do - setting.update!(create_issue: false) - end - - it_behaves_like 'does not process incident issues' - end - end end context 'with invalid payload' do @@ -345,13 +297,6 @@ describe Projects::Prometheus::Alerts::NotifyService do subject end - - it 'does not process issues' do - expect(IncidentManagement::ProcessPrometheusAlertWorker) - .not_to receive(:perform_async) - - subject - end end end diff --git a/spec/services/projects/prometheus/alerts/update_service_spec.rb b/spec/services/projects/prometheus/alerts/update_service_spec.rb index 8a99c2679f7..e831d001838 100644 --- a/spec/services/projects/prometheus/alerts/update_service_spec.rb +++ b/spec/services/projects/prometheus/alerts/update_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Projects::Prometheus::Alerts::UpdateService do +RSpec.describe Projects::Prometheus::Alerts::UpdateService do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } let_it_be(:environment) { create(:environment, project: project) } |