Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-23 15:09:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-23 15:09:47 +0300
commit8f9beefac3774b30e911fb00a68f4c7a5244cf27 (patch)
tree919c3a043f8c10bc3f78f3f6e029acfb6b972556 /spec/services
parente4bf776a8829e5186a0f63603c0be627b891d80e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/services')
-rw-r--r--spec/services/metrics/dashboard/update_dashboard_service_spec.rb46
-rw-r--r--spec/services/notification_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/alerts/create_events_service_spec.rb312
-rw-r--r--spec/services/snippets/create_service_spec.rb6
4 files changed, 365 insertions, 1 deletions
diff --git a/spec/services/metrics/dashboard/update_dashboard_service_spec.rb b/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
index 227041344d7..6ba4b4035e4 100644
--- a/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
@@ -92,6 +92,8 @@ describe Metrics::Dashboard::UpdateDashboardService, :use_clean_rails_memory_sto
end
context 'Files::UpdateService success' do
+ let(:merge_request) { project.merge_requests.last }
+
before do
allow(::Files::UpdateService).to receive(:new).and_return(double(execute: { status: :success }))
end
@@ -107,6 +109,31 @@ describe Metrics::Dashboard::UpdateDashboardService, :use_clean_rails_memory_sto
expect(service_call[:status]).to be :success
expect(service_call[:http_status]).to be :created
expect(service_call[:dashboard]).to match dashboard_details
+ expect(service_call[:merge_request]).to eq(Gitlab::UrlBuilder.build(merge_request))
+ end
+
+ context 'when the merge request does not succeed' do
+ let(:error_message) { 'There was an error' }
+
+ let(:merge_request) do
+ build(:merge_request, target_project: project, source_project: project, author: user)
+ end
+
+ before do
+ merge_request.errors.add(:base, error_message)
+ allow_next_instance_of(::MergeRequests::CreateService) do |mr|
+ allow(mr).to receive(:execute).and_return(merge_request)
+ end
+ end
+
+ it 'returns an appropriate message and status code', :aggregate_failures do
+ result = service_call
+
+ expect(result.keys).to contain_exactly(:message, :http_status, :status, :last_step)
+ expect(result[:status]).to eq(:error)
+ expect(result[:http_status]).to eq(:bad_request)
+ expect(result[:message]).to eq(error_message)
+ end
end
context 'with escaped characters in file name' do
@@ -125,6 +152,25 @@ describe Metrics::Dashboard::UpdateDashboardService, :use_clean_rails_memory_sto
expect(service_call[:dashboard]).to match dashboard_details
end
end
+
+ context 'when pushing to the default branch' do
+ let(:branch) { 'master' }
+
+ it 'does not create a merge request', :aggregate_failures do
+ dashboard_details = {
+ path: '.gitlab/dashboards/custom_dashboard.yml',
+ display_name: 'custom_dashboard.yml',
+ default: false,
+ system_dashboard: false
+ }
+
+ expect(::MergeRequests::CreateService).not_to receive(:new)
+ expect(service_call.keys).to contain_exactly(:dashboard, :http_status, :status)
+ expect(service_call[:status]).to be :success
+ expect(service_call[:http_status]).to be :created
+ expect(service_call[:dashboard]).to match dashboard_details
+ end
+ end
end
context 'Files::UpdateService fails' do
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 8b43844eb96..9fa8f807330 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -2790,7 +2790,7 @@ describe NotificationService, :mailer do
let!(:developer) { create(:user) }
before do
- project.add_master(master)
+ project.add_maintainer(master)
end
it 'sends the email to owners and masters' do
diff --git a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
new file mode 100644
index 00000000000..1d726db6ce3
--- /dev/null
+++ b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
@@ -0,0 +1,312 @@
+# 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.now) }
+ 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.now) }
+ 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] } }
+
+ 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.now, ended_at: Time.now, 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/snippets/create_service_spec.rb b/spec/services/snippets/create_service_spec.rb
index ffad3c8b8e5..26c80ee05b3 100644
--- a/spec/services/snippets/create_service_spec.rb
+++ b/spec/services/snippets/create_service_spec.rb
@@ -193,6 +193,12 @@ describe Snippets::CreateService do
subject
end
+ it 'destroys the snippet_repository' do
+ subject
+
+ expect(SnippetRepository.count).to be_zero
+ end
+
it 'returns the error' do
response = subject