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:
Diffstat (limited to 'spec/services/metrics')
-rw-r--r--spec/services/metrics/dashboard/annotations/create_service_spec.rb161
-rw-r--r--spec/services/metrics/dashboard/annotations/delete_service_spec.rb93
-rw-r--r--spec/services/metrics/dashboard/clone_dashboard_service_spec.rb195
-rw-r--r--spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb60
-rw-r--r--spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb74
-rw-r--r--spec/services/metrics/dashboard/custom_dashboard_service_spec.rb167
-rw-r--r--spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb147
-rw-r--r--spec/services/metrics/dashboard/default_embed_service_spec.rb59
-rw-r--r--spec/services/metrics/dashboard/dynamic_embed_service_spec.rb158
-rw-r--r--spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb103
-rw-r--r--spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb279
-rw-r--r--spec/services/metrics/dashboard/panel_preview_service_spec.rb85
-rw-r--r--spec/services/metrics/dashboard/pod_dashboard_service_spec.rb74
-rw-r--r--spec/services/metrics/dashboard/system_dashboard_service_spec.rb82
-rw-r--r--spec/services/metrics/dashboard/transient_embed_service_spec.rb99
-rw-r--r--spec/services/metrics/dashboard/update_dashboard_service_spec.rb159
-rw-r--r--spec/services/metrics/users_starred_dashboards/create_service_spec.rb73
-rw-r--r--spec/services/metrics/users_starred_dashboards/delete_service_spec.rb41
18 files changed, 0 insertions, 2109 deletions
diff --git a/spec/services/metrics/dashboard/annotations/create_service_spec.rb b/spec/services/metrics/dashboard/annotations/create_service_spec.rb
deleted file mode 100644
index 2bcfa54ead7..00000000000
--- a/spec/services/metrics/dashboard/annotations/create_service_spec.rb
+++ /dev/null
@@ -1,161 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::Annotations::CreateService, feature_category: :metrics do
- let_it_be(:user) { create(:user) }
-
- let(:description) { 'test annotation' }
- let(:dashboard_path) { 'config/prometheus/common_metrics.yml' }
- let(:starting_at) { 15.minutes.ago }
- let(:ending_at) { nil }
- let(:service_instance) { described_class.new(user, annotation_params) }
- let(:annotation_params) do
- {
- environment: environment,
- cluster: cluster,
- description: description,
- dashboard_path: dashboard_path,
- starting_at: starting_at,
- ending_at: ending_at
- }
- end
-
- shared_examples 'executed annotation creation' do
- it 'returns success response', :aggregate_failures do
- annotation = instance_double(::Metrics::Dashboard::Annotation)
- allow(::Metrics::Dashboard::Annotation).to receive(:new).and_return(annotation)
- allow(annotation).to receive(:save).and_return(true)
-
- response = service_instance.execute
-
- expect(response[:status]).to be :success
- expect(response[:annotation]).to be annotation
- end
-
- it 'creates annotation', :aggregate_failures do
- annotation = instance_double(::Metrics::Dashboard::Annotation)
-
- expect(::Metrics::Dashboard::Annotation)
- .to receive(:new).with(annotation_params).and_return(annotation)
- expect(annotation).to receive(:save).and_return(true)
-
- service_instance.execute
- end
- end
-
- shared_examples 'prevented annotation creation' do |message|
- it 'returns error response', :aggregate_failures do
- response = service_instance.execute
-
- expect(response[:status]).to be :error
- expect(response[:message]).to eql message
- end
-
- it 'does not change db state' do
- expect(::Metrics::Dashboard::Annotation).not_to receive(:new)
-
- service_instance.execute
- end
- end
-
- shared_examples 'annotation creation failure' do
- it 'returns error response', :aggregate_failures do
- annotation = instance_double(::Metrics::Dashboard::Annotation)
-
- expect(annotation).to receive(:errors).and_return('Model validation error')
- expect(::Metrics::Dashboard::Annotation)
- .to receive(:new).with(annotation_params).and_return(annotation)
- expect(annotation).to receive(:save).and_return(false)
-
- response = service_instance.execute
-
- expect(response[:status]).to be :error
- expect(response[:message]).to eql 'Model validation error'
- end
- end
-
- describe '.execute' do
- context 'with environment' do
- let(:environment) { create(:environment) }
- let(:cluster) { nil }
-
- context 'with anonymous user' do
- it_behaves_like 'prevented annotation creation', 'You are not authorized to create annotation for selected environment'
- end
-
- context 'with maintainer user' do
- before do
- environment.project.add_maintainer(user)
- end
-
- it_behaves_like 'executed annotation creation'
- end
- end
-
- context 'with cluster' do
- let(:environment) { nil }
-
- context 'with anonymous user' do
- let(:cluster) { create(:cluster, :project) }
-
- it_behaves_like 'prevented annotation creation', 'You are not authorized to create annotation for selected cluster'
- end
-
- context 'with maintainer user' do
- let(:cluster) { create(:cluster, :project) }
-
- before do
- cluster.project.add_maintainer(user)
- end
-
- it_behaves_like 'executed annotation creation'
- end
-
- context 'with owner user' do
- let(:cluster) { create(:cluster, :group) }
-
- before do
- cluster.group.add_owner(user)
- end
-
- it_behaves_like 'executed annotation creation'
- end
- end
-
- context 'non cluster nor environment is supplied' do
- let(:environment) { nil }
- let(:cluster) { nil }
-
- it_behaves_like 'annotation creation failure'
- end
-
- context 'missing dashboard_path' do
- let(:cluster) { create(:cluster, :project) }
- let(:environment) { nil }
- let(:dashboard_path) { nil }
-
- context 'with maintainer user' do
- before do
- cluster.project.add_maintainer(user)
- end
-
- it_behaves_like 'annotation creation failure'
- end
- end
-
- context 'incorrect dashboard_path' do
- let(:cluster) { create(:cluster, :project) }
- let(:environment) { nil }
- let(:dashboard_path) { 'something_incorrect.yml' }
-
- context 'with maintainer user' do
- before do
- cluster.project.add_maintainer(user)
- end
-
- it_behaves_like 'prevented annotation creation', 'Dashboard with requested path can not be found'
- end
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/annotations/delete_service_spec.rb b/spec/services/metrics/dashboard/annotations/delete_service_spec.rb
deleted file mode 100644
index 557d6d95767..00000000000
--- a/spec/services/metrics/dashboard/annotations/delete_service_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::Annotations::DeleteService, feature_category: :metrics do
- let(:user) { create(:user) }
- let(:service_instance) { described_class.new(user, annotation) }
-
- shared_examples 'executed annotation deletion' do
- it 'returns success response', :aggregate_failures do
- expect(annotation).to receive(:destroy).and_return(true)
-
- response = service_instance.execute
-
- expect(response[:status]).to be :success
- end
- end
-
- shared_examples 'prevented annotation deletion' do |message|
- it 'returns error response', :aggregate_failures do
- response = service_instance.execute
-
- expect(response[:status]).to be :error
- expect(response[:message]).to eql message
- end
-
- it 'does not change db state' do
- expect(annotation).not_to receive(:destroy)
-
- service_instance.execute
- end
- end
-
- describe '.execute' do
- context 'with specific environment' do
- let(:annotation) { create(:metrics_dashboard_annotation, environment: environment) }
- let(:environment) { create(:environment) }
-
- context 'with anonymous user' do
- it_behaves_like 'prevented annotation deletion', 'You are not authorized to delete this annotation'
- end
-
- context 'with maintainer user' do
- before do
- environment.project.add_maintainer(user)
- end
-
- it_behaves_like 'executed annotation deletion'
-
- context 'annotation failed to delete' do
- it 'returns error response', :aggregate_failures do
- allow(annotation).to receive(:destroy).and_return(false)
-
- response = service_instance.execute
-
- expect(response[:status]).to be :error
- expect(response[:message]).to eql 'Annotation has not been deleted'
- end
- end
- end
- end
-
- context 'with specific cluster' do
- let(:annotation) { create(:metrics_dashboard_annotation, cluster: cluster, environment: nil) }
-
- context 'with anonymous user' do
- let(:cluster) { create(:cluster, :project) }
-
- it_behaves_like 'prevented annotation deletion', 'You are not authorized to delete this annotation'
- end
-
- context 'with maintainer user' do
- let(:cluster) { create(:cluster, :project) }
-
- before do
- cluster.project.add_maintainer(user)
- end
-
- it_behaves_like 'executed annotation deletion'
- end
-
- context 'with owner user' do
- let(:cluster) { create(:cluster, :group) }
-
- before do
- cluster.group.add_owner(user)
- end
-
- it_behaves_like 'executed annotation deletion'
- end
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb b/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
deleted file mode 100644
index bb11b905a7c..00000000000
--- a/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
+++ /dev/null
@@ -1,195 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::CloneDashboardService, :use_clean_rails_memory_store_caching, feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- describe '#execute' do
- subject(:service_call) { described_class.new(project, user, params).execute }
-
- let(:commit_message) { 'test' }
- let(:branch) { "dashboard_new_branch" }
- let(:dashboard) { 'config/prometheus/common_metrics.yml' }
- let(:file_name) { 'custom_dashboard.yml' }
- let(:file_content_hash) { YAML.safe_load(File.read(dashboard)) }
- let(:params) do
- {
- dashboard: dashboard,
- file_name: file_name,
- commit_message: commit_message,
- branch: branch
- }
- end
-
- context 'user does not have push right to repository' do
- it_behaves_like 'misconfigured dashboard service response with stepable', :forbidden, 'You are not allowed to push into this branch. Create another branch or open a merge request.'
- end
-
- context 'with rights to push to the repository' do
- before do
- project.add_maintainer(user)
- end
-
- context 'wrong target file extension' do
- let(:file_name) { 'custom_dashboard.txt' }
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, 'The file name should have a .yml extension'
- end
-
- context 'wrong source dashboard file' do
- let(:dashboard) { 'config/prometheus/common_metrics_123.yml' }
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :not_found, 'Not found.'
- end
-
- context 'path traversal attack attempt' do
- let(:dashboard) { 'config/prometheus/../database.yml' }
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :not_found, 'Not found.'
- end
-
- context 'path traversal attack attempt on target file' do
- let(:file_name) { '../../custom_dashboard.yml' }
- let(:dashboard_attrs) do
- {
- commit_message: commit_message,
- branch_name: branch,
- start_branch: project.default_branch,
- encoding: 'text',
- file_path: ".gitlab/dashboards/custom_dashboard.yml",
- file_content: file_content_hash.to_yaml
- }
- end
-
- it 'strips target file name to safe value', :aggregate_failures do
- allow(::Gitlab::Metrics::Dashboard::Processor).to receive(:new).and_return(double(process: file_content_hash))
- service_instance = instance_double(::Files::CreateService)
- expect(::Files::CreateService).to receive(:new).with(project, user, dashboard_attrs).and_return(service_instance)
- expect(service_instance).to receive(:execute).and_return(status: :success)
-
- service_call
- end
- end
-
- context 'valid parameters' do
- before do
- allow(::Gitlab::Metrics::Dashboard::Processor).to receive(:new).and_return(double(process: file_content_hash))
- end
-
- it_behaves_like 'valid dashboard cloning process', ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH,
- [
- ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
- ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter
- ]
-
- it_behaves_like 'valid dashboard cloning process', ::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH,
- [
- ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter
- ]
-
- context 'selected branch already exists' do
- let(:branch) { 'existing_branch' }
-
- before do
- project.repository.add_branch(user, branch, 'master')
- end
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, 'There was an error creating the dashboard, branch named: existing_branch already exists.'
-
- # temporary not available function for first iteration
- # follow up issue https://gitlab.com/gitlab-org/gitlab/issues/196237 which
- # require this feature
- # it 'pass correct params to Files::CreateService', :aggregate_failures do
- # project.repository.add_branch(user, branch, 'master')
- #
- # service_instance = instance_double(::Files::CreateService)
- # expect(::Files::CreateService).to receive(:new).with(project, user, dashboard_attrs).and_return(service_instance)
- # expect(service_instance).to receive(:execute).and_return(status: :success)
- #
- # service_call
- # end
- end
-
- context 'blank branch name' do
- let(:branch) { '' }
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, 'There was an error creating the dashboard, branch name is invalid.'
- end
-
- context 'dashboard file already exists' do
- let(:branch) { 'custom_dashboard' }
-
- before do
- Files::CreateService.new(
- project,
- user,
- commit_message: 'Create custom dashboard custom_dashboard.yml',
- branch_name: 'master',
- start_branch: 'master',
- file_path: ".gitlab/dashboards/custom_dashboard.yml",
- file_content: File.read('config/prometheus/common_metrics.yml')
- ).execute
- end
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, "A file with 'custom_dashboard.yml' already exists in custom_dashboard branch"
- end
-
- it 'extends dashboard template path to absolute url' do
- allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: :success }))
-
- expect_file_read(Rails.root.join('config/prometheus/common_metrics.yml'), content: '')
-
- service_call
- end
-
- context 'Files::CreateService success' do
- before do
- allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: :success }))
- end
-
- it 'clears dashboards cache' do
- expect(project.repository).to receive(:refresh_method_caches).with([:metrics_dashboard])
-
- service_call
- end
-
- it 'returns success', :aggregate_failures do
- result = service_call
- dashboard_details = {
- path: '.gitlab/dashboards/custom_dashboard.yml',
- display_name: 'custom_dashboard.yml',
- default: false,
- system_dashboard: false
- }
-
- expect(result[:status]).to be :success
- expect(result[:http_status]).to be :created
- expect(result[:dashboard]).to match dashboard_details
- end
- end
-
- context 'Files::CreateService fails' do
- before do
- allow(::Files::CreateService).to receive(:new).and_return(double(execute: { status: :error }))
- end
-
- it 'does NOT clear dashboards cache' do
- expect(project.repository).not_to receive(:refresh_method_caches)
-
- service_call
- end
-
- it 'returns error' do
- result = service_call
- expect(result[:status]).to be :error
- end
- end
- end
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
deleted file mode 100644
index 53def716de3..00000000000
--- a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::ClusterDashboardService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:cluster_project) { create(:cluster_project) }
- let_it_be(:cluster) { cluster_project.cluster }
- let_it_be(:project) { cluster_project.project }
-
- before do
- project.add_maintainer(user)
- end
-
- describe '.valid_params?' do
- let(:params) { { cluster: cluster, embedded: 'false' } }
-
- subject { described_class.valid_params?(params) }
-
- it { is_expected.to be_truthy }
-
- context 'with matching dashboard_path' do
- let(:params) { { dashboard_path: ::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH } }
-
- it { is_expected.to be_truthy }
- end
-
- context 'missing cluster without dashboard_path' do
- let(:params) { {} }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:service_params) { [project, user, { cluster: cluster, cluster_type: :admin }] }
- let(:service_call) { subject.get_dashboard }
-
- subject { described_class.new(*service_params) }
-
- it_behaves_like 'valid dashboard service response'
- it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
- it_behaves_like 'refreshes cache when dashboard_version is changed'
-
- it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
- let(:dashboard_path) { described_class::DASHBOARD_PATH }
- let(:dashboard_version) { subject.send(:dashboard_version) }
- end
-
- context 'when called with a non-system dashboard' do
- let(:dashboard_path) { 'garbage/dashboard/path' }
-
- # We want to always return the cluster dashboard.
- it_behaves_like 'valid dashboard service response'
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb b/spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb
deleted file mode 100644
index 5d63505e5cc..00000000000
--- a/spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::ClusterMetricsEmbedService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- include MetricsDashboardHelpers
- using RSpec::Parameterized::TableSyntax
-
- let_it_be(:user) { create(:user) }
- let_it_be(:cluster_project) { create(:cluster_project) }
- let_it_be(:cluster) { cluster_project.cluster }
- let_it_be(:project) { cluster_project.project }
-
- before do
- project.add_maintainer(user)
- end
-
- describe '.valid_params?' do
- let(:valid_params) { { cluster: 1, embedded: 'true', group: 'hello', title: 'world', y_label: 'countries' } }
-
- subject { described_class }
-
- it { expect(subject.valid_params?(valid_params)).to be_truthy }
-
- context 'missing all params' do
- let(:params) { {} }
-
- it { expect(subject.valid_params?(params)).to be_falsy }
- end
-
- [:cluster, :embedded, :group, :title, :y_label].each do |param_key|
- it 'returns false with missing param' do
- params = valid_params.except(param_key)
-
- expect(subject.valid_params?(params)).to be_falsy
- end
- end
- end
-
- describe '#get_dashboard' do
- let(:service_params) do
- [
- project,
- user,
- {
- cluster: cluster,
- cluster_type: :project,
- embedded: 'true',
- group: 'Cluster Health',
- title: 'CPU Usage',
- y_label: 'CPU (cores)'
- }
- ]
- end
-
- let(:service_call) { described_class.new(*service_params).get_dashboard }
- let(:panel_groups) { service_call[:dashboard][:panel_groups] }
- let(:panel) { panel_groups.first[:panels].first }
-
- it_behaves_like 'valid embedded dashboard service response'
- it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
-
- it 'returns one panel' do
- expect(panel_groups.size).to eq 1
- expect(panel_groups.first[:panels].size).to eq 1
- end
-
- it 'returns panel by title and y_label' do
- expect(panel[:title]).to eq(service_params.last[:title])
- expect(panel[:y_label]).to eq(service_params.last[:y_label])
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb b/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb
deleted file mode 100644
index 940daa38ae7..00000000000
--- a/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb
+++ /dev/null
@@ -1,167 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
- let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
-
- subject { described_class.new(*service_params) }
-
- before do
- project.add_maintainer(user) if user
- end
-
- describe '#raw_dashboard' do
- let(:project) { project_with_dashboard(dashboard_path) }
-
- it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
- end
-
- describe '#get_dashboard' do
- let(:service_call) { subject.get_dashboard }
-
- context 'when the dashboard does not exist' do
- it_behaves_like 'misconfigured dashboard service response', :not_found
-
- it 'does not update gitlab_metrics_dashboard_processing_time_ms metric', :prometheus do
- service_call
- metric = subject.send(:processing_time_metric)
- labels = subject.send(:processing_time_metric_labels)
-
- expect(metric.get(labels)).to eq(0)
- end
- end
-
- it_behaves_like 'raises error for users with insufficient permissions'
-
- context 'when the dashboard exists' do
- let(:project) { project_with_dashboard(dashboard_path) }
-
- it_behaves_like 'valid dashboard service response'
- it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
-
- it 'caches the unprocessed dashboard for subsequent calls' do
- expect_any_instance_of(described_class)
- .to receive(:get_raw_dashboard)
- .once
- .and_call_original
-
- described_class.new(*service_params).get_dashboard
- described_class.new(*service_params).get_dashboard
- end
-
- it 'tracks panel type' do
- allow(::Gitlab::Tracking).to receive(:event).and_call_original
-
- described_class.new(*service_params).get_dashboard
-
- expect(::Gitlab::Tracking).to have_received(:event)
- .with('MetricsDashboard::Chart', 'chart_rendered', { label: 'area-chart' })
- .at_least(:once)
- end
-
- context 'with metric in database' do
- let!(:prometheus_metric) do
- create(:prometheus_metric, project: project, identifier: 'metric_a1', group: 'custom')
- end
-
- it 'includes metric_id' do
- dashboard = described_class.new(*service_params).get_dashboard
-
- metric_id = dashboard[:dashboard][:panel_groups].find { |panel_group| panel_group[:group] == 'Group A' }
- .fetch(:panels).find { |panel| panel[:title] == 'Super Chart A1' }
- .fetch(:metrics).find { |metric| metric[:id] == 'metric_a1' }
- .fetch(:metric_id)
-
- expect(metric_id).to eq(prometheus_metric.id)
- end
- end
-
- context 'and the dashboard is then deleted' do
- it 'does not return the previously cached dashboard' do
- described_class.new(*service_params).get_dashboard
-
- delete_project_dashboard(project, user, dashboard_path)
-
- expect_any_instance_of(described_class)
- .to receive(:get_raw_dashboard)
- .once
- .and_call_original
-
- described_class.new(*service_params).get_dashboard
- end
- end
- end
-
- context 'when the dashboard is configured incorrectly' do
- let(:project) { project_with_dashboard(dashboard_path, {}) }
-
- it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
- end
- end
-
- describe '.all_dashboard_paths' do
- let(:all_dashboards) { described_class.all_dashboard_paths(project) }
-
- context 'when there are no project dashboards' do
- it 'returns an empty array' do
- expect(all_dashboards).to be_empty
- end
- end
-
- context 'when there are project dashboards available' do
- let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
- let(:project) { project_with_dashboard(dashboard_path) }
-
- it 'returns the dashboard attributes' do
- expect(all_dashboards).to eq(
- [{
- path: dashboard_path,
- display_name: 'test.yml',
- default: false,
- system_dashboard: false,
- out_of_the_box_dashboard: false
- }]
- )
- end
-
- it 'caches repo file list' do
- expect(Gitlab::Metrics::Dashboard::RepoDashboardFinder).to receive(:list_dashboards)
- .with(project)
- .once
- .and_call_original
-
- described_class.all_dashboard_paths(project)
- described_class.all_dashboard_paths(project)
- end
- end
- end
-
- describe '.valid_params?' do
- let(:params) { { dashboard_path: '.gitlab/dashboard/test.yml' } }
-
- subject { described_class.valid_params?(params) }
-
- it { is_expected.to be_truthy }
-
- context 'missing dashboard_path' do
- let(:params) { {} }
-
- it { is_expected.to be_falsey }
- end
-
- context 'empty dashboard_path' do
- let(:params) { { dashboard_path: '' } }
-
- it { is_expected.to be_falsey }
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
deleted file mode 100644
index 8117296b048..00000000000
--- a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
+++ /dev/null
@@ -1,147 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::CustomMetricEmbedService, feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:project, reload: true) { build(:project) }
- let_it_be(:user) { create(:user) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- before do
- project.add_maintainer(user) if user
- end
-
- let(:dashboard_path) { system_dashboard_path }
- let(:group) { business_metric_title }
- let(:title) { 'title' }
- let(:y_label) { 'y_label' }
-
- describe '.valid_params?' do
- let(:valid_params) do
- {
- embedded: true,
- dashboard_path: dashboard_path,
- group: group,
- title: title,
- y_label: y_label
- }
- end
-
- subject { described_class.valid_params?(params) }
-
- let(:params) { valid_params }
-
- it { is_expected.to be_truthy }
-
- context 'missing embedded' do
- let(:params) { valid_params.except(:embedded) }
-
- it { is_expected.to be_falsey }
- end
-
- context 'not embedded' do
- let(:params) { valid_params.merge(embedded: 'false') }
-
- it { is_expected.to be_falsey }
- end
-
- context 'non-system dashboard' do
- let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
-
- it { is_expected.to be_falsey }
- end
-
- context 'undefined dashboard' do
- let(:params) { valid_params.except(:dashboard_path) }
-
- it { is_expected.to be_truthy }
- end
-
- context 'non-custom metric group' do
- let(:group) { 'Different Group' }
-
- it { is_expected.to be_falsey }
- end
-
- context 'missing group' do
- let(:group) { nil }
-
- it { is_expected.to be_falsey }
- end
-
- context 'missing title' do
- let(:title) { nil }
-
- it { is_expected.to be_falsey }
- end
-
- context 'undefined y-axis label' do
- let(:params) { valid_params.except(:y_label) }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:service_params) do
- [
- project,
- user,
- {
- embedded: true,
- environment: environment,
- dashboard_path: dashboard_path,
- group: group,
- title: title,
- y_label: y_label
- }
- ]
- end
-
- let(:service_call) { described_class.new(*service_params).get_dashboard }
-
- it_behaves_like 'misconfigured dashboard service response', :not_found
- it_behaves_like 'raises error for users with insufficient permissions'
-
- context 'the custom metric exists' do
- let!(:metric) { create(:prometheus_metric, project: project) }
-
- it_behaves_like 'valid embedded dashboard service response'
-
- it 'does not cache the unprocessed dashboard' do
- # Fail spec if any method of Cache class is called.
- stub_const('Gitlab::Metrics::Dashboard::Cache', double)
-
- described_class.new(*service_params).get_dashboard
- end
-
- context 'multiple metrics meet criteria' do
- let!(:metric_2) { create(:prometheus_metric, project: project, query: 'avg(metric_2)') }
-
- it_behaves_like 'valid embedded dashboard service response'
-
- it 'includes both metrics in a single panel' do
- result = service_call
-
- panel_groups = result[:dashboard][:panel_groups]
- panels = panel_groups[0][:panels]
- metrics = panels[0][:metrics]
- queries = metrics.map { |metric| metric[:query_range] }
-
- expect(panel_groups.length).to eq(1)
- expect(panels.length).to eq(1)
- expect(metrics.length).to eq(2)
- expect(queries).to include('avg(metric_2)', 'avg(metric)')
- end
- end
- end
-
- context 'when the metric exists in another project' do
- let!(:metric) { create(:prometheus_metric, project: create(:project)) }
-
- it_behaves_like 'misconfigured dashboard service response', :not_found
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/default_embed_service_spec.rb b/spec/services/metrics/dashboard/default_embed_service_spec.rb
deleted file mode 100644
index 6ef248f6b09..00000000000
--- a/spec/services/metrics/dashboard/default_embed_service_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::DefaultEmbedService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:project) { build(:project) }
- let_it_be(:user) { create(:user) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- before do
- project.add_maintainer(user) if user
- end
-
- describe '.valid_params?' do
- let(:params) { { embedded: true } }
-
- subject { described_class.valid_params?(params) }
-
- it { is_expected.to be_truthy }
-
- context 'missing embedded' do
- let(:params) { {} }
-
- it { is_expected.to be_falsey }
- end
-
- context 'not embedded' do
- let(:params) { { embedded: 'false' } }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:service_params) { [project, user, { environment: environment }] }
- let(:service_call) { described_class.new(*service_params).get_dashboard }
-
- it_behaves_like 'valid embedded dashboard service response'
- it_behaves_like 'raises error for users with insufficient permissions'
-
- it 'caches the unprocessed dashboard for subsequent calls' do
- system_service = Metrics::Dashboard::SystemDashboardService
-
- expect(system_service).to receive(:new).once.and_call_original
-
- described_class.new(*service_params).get_dashboard
- described_class.new(*service_params).get_dashboard
- end
-
- context 'when called with a non-system dashboard' do
- let(:dashboard_path) { 'garbage/dashboard/path' }
-
- it_behaves_like 'valid embedded dashboard service response'
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb b/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb
deleted file mode 100644
index 1643f552a70..00000000000
--- a/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb
+++ /dev/null
@@ -1,158 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::DynamicEmbedService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:project) { build(:project) }
- let_it_be(:user) { create(:user) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- before do
- project.add_maintainer(user) if user
- end
-
- let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
- let(:group) { 'Group A' }
- let(:title) { 'Super Chart A1' }
- let(:y_label) { 'y_label' }
-
- describe '.valid_params?' do
- let(:valid_params) do
- {
- embedded: true,
- dashboard_path: dashboard_path,
- group: group,
- title: title,
- y_label: y_label
- }
- end
-
- subject { described_class.valid_params?(params) }
-
- let(:params) { valid_params }
-
- it { is_expected.to be_truthy }
-
- context 'missing embedded' do
- let(:params) { valid_params.except(:embedded) }
-
- it { is_expected.to be_falsey }
- end
-
- context 'not embedded' do
- let(:params) { valid_params.merge(embedded: 'false') }
-
- it { is_expected.to be_falsey }
- end
-
- context 'undefined dashboard' do
- let(:params) { valid_params.except(:dashboard_path) }
-
- it { is_expected.to be_truthy }
- end
-
- context 'missing dashboard' do
- let(:dashboard) { '' }
-
- it { is_expected.to be_truthy }
- end
-
- context 'missing group' do
- let(:group) { '' }
-
- it { is_expected.to be_falsey }
- end
-
- context 'missing title' do
- let(:title) { '' }
-
- it { is_expected.to be_falsey }
- end
-
- context 'undefined y-axis label' do
- let(:params) { valid_params.except(:y_label) }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:service_params) do
- [
- project,
- user,
- {
- environment: environment,
- dashboard_path: dashboard_path,
- group: group,
- title: title,
- y_label: y_label
- }
- ]
- end
-
- let(:service_call) { described_class.new(*service_params).get_dashboard }
-
- context 'when the dashboard does not exist' do
- it_behaves_like 'misconfigured dashboard service response', :not_found
- end
-
- context 'when the dashboard is exists' do
- let(:project) { project_with_dashboard(dashboard_path) }
-
- it_behaves_like 'valid embedded dashboard service response'
- it_behaves_like 'raises error for users with insufficient permissions'
-
- it 'caches the unprocessed dashboard for subsequent calls' do
- expect(YAML).to receive(:safe_load).once.and_call_original
-
- described_class.new(*service_params).get_dashboard
- described_class.new(*service_params).get_dashboard
- end
-
- context 'when the specified group is not present on the dashboard' do
- let(:group) { 'Group Not Found' }
-
- it_behaves_like 'misconfigured dashboard service response', :not_found
- end
-
- context 'when the specified title is not present on the dashboard' do
- let(:title) { 'Title Not Found' }
-
- it_behaves_like 'misconfigured dashboard service response', :not_found
- end
-
- context 'when the specified y-axis label is not present on the dashboard' do
- let(:y_label) { 'Y-Axis Not Found' }
-
- it_behaves_like 'misconfigured dashboard service response', :not_found
- end
- end
-
- shared_examples 'uses system dashboard' do
- it 'uses the overview dashboard' do
- expect(Gitlab::Metrics::Dashboard::Finder)
- .to receive(:find_raw)
- .with(project, dashboard_path: system_dashboard_path)
- .once
-
- service_call
- end
- end
-
- context 'when the dashboard is nil' do
- let(:dashboard_path) { nil }
-
- it_behaves_like 'uses system dashboard'
- end
-
- context 'when the dashboard is not present' do
- let(:dashboard_path) { '' }
-
- it_behaves_like 'uses system dashboard'
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb b/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
deleted file mode 100644
index 25812a492b2..00000000000
--- a/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::GitlabAlertEmbedService, feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:alert) { create(:prometheus_alert) }
- let_it_be(:project) { alert.project }
- let_it_be(:user) { create(:user) }
-
- let(:alert_id) { alert.id }
-
- before_all do
- project.add_maintainer(user)
- end
-
- describe '.valid_params?' do
- let(:valid_params) do
- {
- embedded: true,
- prometheus_alert_id: alert_id
- }
- end
-
- subject { described_class.valid_params?(params) }
-
- let(:params) { valid_params }
-
- it { is_expected.to be_truthy }
-
- context 'missing embedded' do
- let(:params) { valid_params.except(:embedded) }
-
- it { is_expected.to be_falsey }
- end
-
- context 'not embedded' do
- let(:params) { valid_params.merge(embedded: 'false') }
-
- it { is_expected.to be_falsey }
- end
-
- context 'missing alert id' do
- let(:params) { valid_params.except(:prometheus_alert_id) }
-
- it { is_expected.to be_falsey }
- end
-
- context 'missing alert id' do
- let(:params) { valid_params.merge(prometheus_alert_id: 'none') }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:service_params) do
- [
- project,
- user,
- {
- embedded: true,
- prometheus_alert_id: alert_id
- }
- ]
- end
-
- let(:service_call) { described_class.new(*service_params).get_dashboard }
-
- context 'when alerting is available' do
- it_behaves_like 'valid embedded dashboard service response'
- it_behaves_like 'raises error for users with insufficient permissions'
-
- it 'generates an panel based on the alert' do
- result = service_call
- panel = result[:dashboard][:panel_groups][0][:panels][0]
- metric = panel[:metrics].first
-
- expect(panel[:metrics].length).to eq 1
- expect(panel).to include(
- title: alert.prometheus_metric.title,
- y_label: alert.prometheus_metric.y_label,
- type: 'area-chart'
- )
- expect(metric[:metric_id]).to eq alert.prometheus_metric_id
- end
-
- context 'when the metric does not exist' do
- let(:alert_id) { -4 }
-
- it_behaves_like 'misconfigured dashboard service response', :not_found
- end
-
- it 'does not cache the unprocessed dashboard' do
- # Fail spec if any method of Cache class is called.
- stub_const('Gitlab::Metrics::Dashboard::Cache', double)
-
- described_class.new(*service_params).get_dashboard
- end
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb b/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb
deleted file mode 100644
index 877a455ea44..00000000000
--- a/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb
+++ /dev/null
@@ -1,279 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::GrafanaMetricEmbedService, feature_category: :metrics do
- include MetricsDashboardHelpers
- include ReactiveCachingHelpers
- include GrafanaApiHelpers
-
- let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
- let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
-
- let(:grafana_url) do
- valid_grafana_dashboard_link(grafana_integration.grafana_url)
- end
-
- before_all do
- project.add_maintainer(user)
- end
-
- describe '.valid_params?' do
- let(:valid_params) { { embedded: true, grafana_url: grafana_url } }
-
- subject { described_class.valid_params?(params) }
-
- let(:params) { valid_params }
-
- it { is_expected.to be_truthy }
-
- context 'missing embedded' do
- let(:params) { valid_params.except(:embedded) }
-
- it { is_expected.to be_falsey }
- end
-
- context 'not embedded' do
- let(:params) { valid_params.merge(embedded: 'false') }
-
- it { is_expected.to be_falsey }
- end
-
- context 'undefined grafana_url' do
- let(:params) { valid_params.except(:grafana_url) }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '.from_cache' do
- let(:params) { [project.id, user.id, grafana_url] }
-
- subject { described_class.from_cache(*params) }
-
- it 'initializes an instance of GrafanaMetricEmbedService' do
- expect(subject).to be_an_instance_of(described_class)
- expect(subject.project).to eq(project)
- expect(subject.current_user).to eq(user)
- expect(subject.params[:grafana_url]).to eq(grafana_url)
- end
-
- context 'with unknown users' do
- let(:params) { [project.id, current_user_id, grafana_url] }
-
- context 'when anonymous' do
- where(:current_user_id) do
- [nil, '']
- end
-
- with_them do
- it 'sets current_user as nil' do
- expect(subject.current_user).to be_nil
- end
- end
- end
-
- context 'when invalid' do
- let(:current_user_id) { non_existing_record_id }
-
- it 'raise record not found error' do
- expect { subject }
- .to raise_error(ActiveRecord::RecordNotFound, /Couldn't find User/)
- end
- end
- end
- end
-
- describe '#get_dashboard', :use_clean_rails_memory_store_caching do
- let(:service_params) do
- [
- project,
- user,
- {
- embedded: true,
- grafana_url: grafana_url
- }
- ]
- end
-
- let(:service) { described_class.new(*service_params) }
- let(:service_call) { service.get_dashboard }
-
- context 'without caching' do
- before do
- synchronous_reactive_cache(service)
- end
-
- it_behaves_like 'raises error for users with insufficient permissions'
-
- context 'without a grafana integration' do
- before do
- allow(project).to receive(:grafana_integration).and_return(nil)
- end
-
- it_behaves_like 'misconfigured dashboard service response', :bad_request
- end
-
- context 'when grafana cannot be reached' do
- before do
- allow(grafana_integration.client).to receive(:get_dashboard).and_raise(::Grafana::Client::Error)
- end
-
- it_behaves_like 'misconfigured dashboard service response', :service_unavailable
- end
-
- context 'when panelId is missing' do
- let(:grafana_url) do
- grafana_integration.grafana_url +
- '/d/XDaNK6amz/gitlab-omnibus-redis' \
- '?from=1570397739557&to=1570484139557'
- end
-
- before do
- stub_dashboard_request(grafana_integration.grafana_url)
- end
-
- it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
- end
-
- context 'when uid is missing' do
- let(:grafana_url) { grafana_integration.grafana_url + '/d/' }
-
- before do
- stub_dashboard_request(grafana_integration.grafana_url)
- end
-
- it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
- end
-
- context 'when the dashboard response contains misconfigured json' do
- before do
- stub_dashboard_request(grafana_integration.grafana_url, body: '')
- end
-
- it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
- end
-
- context 'when the datasource response contains misconfigured json' do
- before do
- stub_dashboard_request(grafana_integration.grafana_url)
- stub_datasource_request(grafana_integration.grafana_url, body: '')
- end
-
- it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
- end
-
- context 'when the embed was created successfully' do
- before do
- stub_dashboard_request(grafana_integration.grafana_url)
- stub_datasource_request(grafana_integration.grafana_url)
- end
-
- context 'when project is private and user is member' do
- it_behaves_like 'valid embedded dashboard service response'
- end
-
- context 'when project is public and user is anonymous' do
- let(:project) { create(:project, :public) }
- let(:user) { nil }
- let(:grafana_integration) { create(:grafana_integration, project: project) }
-
- it_behaves_like 'valid embedded dashboard service response'
- end
- end
- end
-
- context 'with caching', :use_clean_rails_memory_store_caching do
- let(:cache_params) { [project.id, user.id, grafana_url] }
-
- context 'when value not present in cache' do
- it 'returns nil' do
- expect(ExternalServiceReactiveCachingWorker)
- .to receive(:perform_async)
- .with(service.class, service.id, *cache_params)
-
- expect(service_call).to eq(nil)
- end
- end
-
- context 'when value present in cache' do
- let(:return_value) { { 'http_status' => :ok, 'dashboard' => '{}' } }
-
- before do
- stub_reactive_cache(service, return_value, cache_params)
- end
-
- it 'returns cached value' do
- expect(ReactiveCachingWorker)
- .not_to receive(:perform_async)
- .with(service.class, service.id, *cache_params)
-
- expect(service_call[:http_status]).to eq(return_value[:http_status])
- expect(service_call[:dashboard]).to eq(return_value[:dashboard])
- end
- end
- end
- end
-end
-
-RSpec.describe Metrics::Dashboard::GrafanaUidParser do
- let_it_be(:grafana_integration) { create(:grafana_integration) }
- let_it_be(:project) { grafana_integration.project }
-
- subject { described_class.new(grafana_url, project).parse }
-
- context 'with a Grafana-defined uid' do
- let(:grafana_url) { grafana_integration.grafana_url + '/d/XDaNK6amz/?panelId=1' }
-
- it { is_expected.to eq 'XDaNK6amz' }
- end
-
- context 'with a user-defined uid' do
- let(:grafana_url) { grafana_integration.grafana_url + '/d/pgbouncer-main/pgbouncer-overview?panelId=1' }
-
- it { is_expected.to eq 'pgbouncer-main' }
- end
-
- context 'when a uid is not present' do
- let(:grafana_url) { grafana_integration.grafana_url }
-
- it { is_expected.to be nil }
- end
-
- context 'when the url starts with unrelated content' do
- let(:grafana_url) { 'js:' + grafana_integration.grafana_url }
-
- it { is_expected.to be nil }
- end
-end
-
-RSpec.describe Metrics::Dashboard::DatasourceNameParser do
- include GrafanaApiHelpers
-
- let(:grafana_url) { valid_grafana_dashboard_link('https://gitlab.grafana.net') }
- let(:grafana_dashboard) { Gitlab::Json.parse(fixture_file('grafana/dashboard_response.json'), symbolize_names: true) }
-
- subject { described_class.new(grafana_url, grafana_dashboard).parse }
-
- it { is_expected.to eq 'GitLab Omnibus' }
-
- context 'when the panelId is missing from the url' do
- let(:grafana_url) { 'https:/gitlab.grafana.net/d/jbdbks/' }
-
- it { is_expected.to be nil }
- end
-
- context 'when the panel is not present' do
- # We're looking for panelId of 8, but only 6 is present
- let(:grafana_dashboard) { { dashboard: { panels: [{ id: 6 }] } } }
-
- it { is_expected.to be nil }
- end
-
- context 'when the dashboard panel does not have a datasource' do
- let(:grafana_dashboard) { { dashboard: { panels: [{ id: 8 }] } } }
-
- it { is_expected.to be nil }
- end
-end
diff --git a/spec/services/metrics/dashboard/panel_preview_service_spec.rb b/spec/services/metrics/dashboard/panel_preview_service_spec.rb
deleted file mode 100644
index 584be717d7c..00000000000
--- a/spec/services/metrics/dashboard/panel_preview_service_spec.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::PanelPreviewService, feature_category: :metrics do
- let_it_be(:project) { create(:project) }
- let_it_be(:environment) { create(:environment, project: project) }
- let_it_be(:panel_yml) do
- <<~YML
- ---
- title: test panel
- YML
- end
-
- let_it_be(:dashboard) do
- {
- panel_groups: [
- {
- panels: [{ 'title' => 'test panel' }]
- }
- ]
- }
- end
-
- describe '#execute' do
- subject(:service_response) { described_class.new(project, panel_yml, environment).execute }
-
- context "valid panel's yaml" do
- before do
- allow_next_instance_of(::Gitlab::Metrics::Dashboard::Processor) do |processor|
- allow(processor).to receive(:process).and_return(dashboard)
- end
- end
-
- it 'returns success service response' do
- expect(service_response.success?).to be_truthy
- end
-
- it 'returns processed panel' do
- expect(service_response.payload).to eq('title' => 'test panel')
- end
-
- it 'uses dashboard processor' do
- sequence = [
- ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
- ::Gitlab::Metrics::Dashboard::Stages::MetricEndpointInserter,
- ::Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter,
- ::Gitlab::Metrics::Dashboard::Stages::UrlValidator
- ]
- processor_params = [project, dashboard, sequence, environment: environment]
-
- expect_next_instance_of(::Gitlab::Metrics::Dashboard::Processor, *processor_params) do |processor|
- expect(processor).to receive(:process).and_return(dashboard)
- end
-
- service_response
- end
- end
-
- context "invalid panel's yaml" do
- [
- Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError,
- Gitlab::Config::Loader::Yaml::NotHashError,
- Gitlab::Config::Loader::Yaml::DataTooLargeError,
- Gitlab::Config::Loader::FormatError
- ].each do |error_class|
- context "with #{error_class}" do
- before do
- allow_next_instance_of(::Gitlab::Metrics::Dashboard::Processor) do |processor|
- allow(processor).to receive(:process).and_raise(error_class.new('error'))
- end
- end
-
- it 'returns error service response' do
- expect(service_response.error?).to be_truthy
- end
-
- it 'returns error message' do
- expect(service_response.message).to eq('error')
- end
- end
- end
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb b/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
deleted file mode 100644
index a6fcb6b4842..00000000000
--- a/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_caching,
- feature_category: :cell do
- include MetricsDashboardHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- let(:dashboard_path) { described_class::DASHBOARD_PATH }
- let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
-
- before do
- project.add_maintainer(user)
- end
-
- subject { described_class.new(*service_params) }
-
- describe '#raw_dashboard' do
- it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
- end
-
- describe '.valid_params?' do
- let(:params) { { dashboard_path: described_class::DASHBOARD_PATH } }
-
- subject { described_class.valid_params?(params) }
-
- it { is_expected.to be_truthy }
-
- context 'missing dashboard_path' do
- let(:params) { {} }
-
- it { is_expected.to be_falsey }
- end
-
- context 'non-matching dashboard_path' do
- let(:params) { { dashboard_path: 'path/to/bunk.yml' } }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:service_call) { subject.get_dashboard }
-
- it_behaves_like 'valid dashboard service response'
- it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
- it_behaves_like 'refreshes cache when dashboard_version is changed'
- it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
-
- it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
- let(:dashboard_version) { subject.send(:dashboard_version) }
- end
- end
-
- describe '.all_dashboard_paths' do
- it 'returns the dashboard attributes' do
- all_dashboards = described_class.all_dashboard_paths(project)
-
- expect(all_dashboards).to eq(
- [{
- path: described_class::DASHBOARD_PATH,
- display_name: described_class::DASHBOARD_NAME,
- default: false,
- system_dashboard: false,
- out_of_the_box_dashboard: true
- }]
- )
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/system_dashboard_service_spec.rb b/spec/services/metrics/dashboard/system_dashboard_service_spec.rb
deleted file mode 100644
index b08b980e50e..00000000000
--- a/spec/services/metrics/dashboard/system_dashboard_service_spec.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- let(:dashboard_path) { described_class::DASHBOARD_PATH }
- let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
-
- subject { described_class.new(*service_params) }
-
- before do
- project.add_maintainer(user) if user
- end
-
- describe '#raw_dashboard' do
- it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
- end
-
- describe '#get_dashboard' do
- let(:service_call) { subject.get_dashboard }
-
- it_behaves_like 'valid dashboard service response'
- it_behaves_like 'raises error for users with insufficient permissions'
- it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
- it_behaves_like 'refreshes cache when dashboard_version is changed'
- it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
-
- it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
- let(:dashboard_version) { subject.send(:dashboard_version) }
- end
-
- context 'when called with a non-system dashboard' do
- let(:dashboard_path) { 'garbage/dashboard/path' }
-
- # We want to always return the system dashboard.
- it_behaves_like 'valid dashboard service response'
- end
- end
-
- describe '.all_dashboard_paths' do
- it 'returns the dashboard attributes' do
- all_dashboards = described_class.all_dashboard_paths(project)
-
- expect(all_dashboards).to eq(
- [{
- path: described_class::DASHBOARD_PATH,
- display_name: described_class::DASHBOARD_NAME,
- default: true,
- system_dashboard: true,
- out_of_the_box_dashboard: true
- }]
- )
- end
- end
-
- describe '.valid_params?' do
- let(:params) { { dashboard_path: described_class::DASHBOARD_PATH } }
-
- subject { described_class.valid_params?(params) }
-
- it { is_expected.to be_truthy }
-
- context 'missing dashboard_path' do
- let(:params) { {} }
-
- it { is_expected.to be_falsey }
- end
-
- context 'non-matching dashboard_path' do
- let(:params) { { dashboard_path: 'path/to/bunk.yml' } }
-
- it { is_expected.to be_falsey }
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/transient_embed_service_spec.rb b/spec/services/metrics/dashboard/transient_embed_service_spec.rb
deleted file mode 100644
index 1e3ccde6ae3..00000000000
--- a/spec/services/metrics/dashboard/transient_embed_service_spec.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::TransientEmbedService, :use_clean_rails_memory_store_caching,
- feature_category: :metrics do
- let_it_be(:project) { build(:project) }
- let_it_be(:user) { create(:user) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- before do
- project.add_maintainer(user) if user
- end
-
- describe '.valid_params?' do
- let(:params) { { embedded: 'true', embed_json: '{}' } }
-
- subject { described_class.valid_params?(params) }
-
- it { is_expected.to be_truthy }
-
- context 'missing embedded' do
- let(:params) { { embed_json: '{}' } }
-
- it { is_expected.to be_falsey }
- end
-
- context 'not embedded' do
- let(:params) { { embedded: 'false', embed_json: '{}' } }
-
- it { is_expected.to be_falsey }
- end
-
- context 'missing embed_json' do
- let(:params) { { embedded: 'true' } }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#get_dashboard' do
- let(:embed_json) { get_embed_json }
- let(:service_params) { [project, user, { environment: environment, embedded: 'true', embed_json: embed_json }] }
- let(:service_call) { described_class.new(*service_params).get_dashboard }
-
- it_behaves_like 'valid embedded dashboard service response'
- it_behaves_like 'raises error for users with insufficient permissions'
-
- it 'caches the unprocessed dashboard for subsequent calls' do
- expect_any_instance_of(described_class)
- .to receive(:get_raw_dashboard)
- .once
- .and_call_original
-
- described_class.new(*service_params).get_dashboard
- described_class.new(*service_params).get_dashboard
- end
-
- it 'caches unique requests separately' do
- alt_embed_json = get_embed_json('area-chart')
- alt_service_params = [project, user, { environment: environment, embedded: 'true', embed_json: alt_embed_json }]
-
- embed = described_class.new(*service_params).get_dashboard
- alt_embed = described_class.new(*alt_service_params).get_dashboard
-
- expect(embed).not_to eq(alt_embed)
- expect(get_type_for_embed(embed)).to eq('line-graph')
- expect(get_type_for_embed(alt_embed)).to eq('area-chart')
- end
-
- context 'when embed_json cannot be parsed as json' do
- let(:embed_json) { '' }
-
- it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
- end
-
- private
-
- def get_embed_json(type = 'line-graph')
- {
- panel_groups: [{
- panels: [{
- type: type,
- title: 'title',
- y_label: 'y_label',
- metrics: [{
- query_range: 'up',
- label: 'y_label'
- }]
- }]
- }]
- }.to_json
- end
-
- def get_type_for_embed(embed)
- embed[:dashboard][:panel_groups][0][:panels][0][:type]
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/update_dashboard_service_spec.rb b/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
deleted file mode 100644
index 15bbe9f9364..00000000000
--- a/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::Dashboard::UpdateDashboardService, :use_clean_rails_memory_store_caching, feature_category: :metrics do
- include MetricsDashboardHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:environment) { create(:environment, project: project) }
-
- describe '#execute' do
- subject(:service_call) { described_class.new(project, user, params).execute }
-
- let(:commit_message) { 'test' }
- let(:branch) { 'dashboard_new_branch' }
- let(:dashboard) { 'config/prometheus/common_metrics.yml' }
- let(:file_name) { 'custom_dashboard.yml' }
- let(:file_content_hash) { YAML.safe_load(File.read(dashboard)) }
- let(:params) do
- {
- file_name: file_name,
- file_content: file_content_hash,
- commit_message: commit_message,
- branch: branch
- }
- end
-
- context 'user does not have push right to repository' do
- it_behaves_like 'misconfigured dashboard service response with stepable', :forbidden, 'You are not allowed to push into this branch. Create another branch or open a merge request.'
- end
-
- context 'with rights to push to the repository' do
- before do
- project.add_maintainer(user)
- end
-
- context 'path traversal attack attempt' do
- context 'with a yml extension' do
- let(:file_name) { 'config/prometheus/../database.yml' }
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, "A file with this name doesn't exist"
- end
-
- context 'without a yml extension' do
- let(:file_name) { '../../..../etc/passwd' }
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, 'The file name should have a .yml extension'
- end
- end
-
- context 'valid parameters' do
- it_behaves_like 'valid dashboard update process'
- end
-
- context 'selected branch already exists' do
- let(:branch) { 'existing_branch' }
-
- before do
- project.repository.add_branch(user, branch, 'master')
- end
-
- it_behaves_like 'misconfigured dashboard service response with stepable', :bad_request, 'There was an error updating the dashboard, branch named: existing_branch already exists.'
- 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
-
- it 'returns success', :aggregate_failures do
- dashboard_details = {
- path: '.gitlab/dashboards/custom_dashboard.yml',
- display_name: 'custom_dashboard.yml',
- default: false,
- system_dashboard: false
- }
-
- 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
- let(:file_name) { "custom_dashboard%26copy.yml" }
-
- it 'escapes the special characters', :aggregate_failures do
- dashboard_details = {
- path: '.gitlab/dashboards/custom_dashboard&copy.yml',
- display_name: 'custom_dashboard&copy.yml',
- default: false,
- system_dashboard: false
- }
-
- 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
-
- 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
- before do
- allow(::Files::UpdateService).to receive(:new).and_return(double(execute: { status: :error }))
- end
-
- it 'returns error' do
- expect(service_call[:status]).to be :error
- end
- end
- end
- end
-end
diff --git a/spec/services/metrics/users_starred_dashboards/create_service_spec.rb b/spec/services/metrics/users_starred_dashboards/create_service_spec.rb
deleted file mode 100644
index e08bdca8410..00000000000
--- a/spec/services/metrics/users_starred_dashboards/create_service_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::UsersStarredDashboards::CreateService, feature_category: :metrics do
- let_it_be(:user) { create(:user) }
-
- let(:dashboard_path) { 'config/prometheus/common_metrics.yml' }
- let(:service_instance) { described_class.new(user, project, dashboard_path) }
- let(:project) { create(:project) }
- let(:starred_dashboard_params) do
- {
- user: user,
- project: project,
- dashboard_path: dashboard_path
- }
- end
-
- shared_examples 'prevented starred dashboard creation' do |message|
- it 'returns error response', :aggregate_failures do
- expect(Metrics::UsersStarredDashboard).not_to receive(:new)
-
- response = service_instance.execute
-
- expect(response.status).to be :error
- expect(response.message).to eql message
- end
- end
-
- describe '.execute' do
- context 'with anonymous user' do
- it_behaves_like 'prevented starred dashboard creation', 'You are not authorized to add star to this dashboard'
- end
-
- context 'with reporter user' do
- before do
- project.add_reporter(user)
- end
-
- context 'incorrect dashboard_path' do
- let(:dashboard_path) { 'something_incorrect.yml' }
-
- it_behaves_like 'prevented starred dashboard creation', 'Dashboard with requested path can not be found'
- end
-
- context 'with valid dashboard path' do
- it 'creates starred dashboard and returns success response', :aggregate_failures do
- expect_next_instance_of(Metrics::UsersStarredDashboard, starred_dashboard_params) do |starred_dashboard|
- expect(starred_dashboard).to receive(:save).and_return true
- end
-
- response = service_instance.execute
-
- expect(response.status).to be :success
- end
-
- context 'Metrics::UsersStarredDashboard has validation errors' do
- it 'returns error response', :aggregate_failures do
- expect_next_instance_of(Metrics::UsersStarredDashboard, starred_dashboard_params) do |starred_dashboard|
- expect(starred_dashboard).to receive(:save).and_return(false)
- expect(starred_dashboard).to receive(:errors).and_return(double(messages: { base: ['Model validation error'] }))
- end
-
- response = service_instance.execute
-
- expect(response.status).to be :error
- expect(response.message).to eql(base: ['Model validation error'])
- end
- end
- end
- end
- end
-end
diff --git a/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb b/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb
deleted file mode 100644
index 8c4bcecc239..00000000000
--- a/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Metrics::UsersStarredDashboards::DeleteService, feature_category: :metrics do
- subject(:service_instance) { described_class.new(user, project, dashboard_path) }
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
-
- describe '#execute' do
- let_it_be(:user_starred_dashboard_1) { create(:metrics_users_starred_dashboard, user: user, project: project, dashboard_path: 'dashboard_1') }
- let_it_be(:user_starred_dashboard_2) { create(:metrics_users_starred_dashboard, user: user, project: project) }
- let_it_be(:other_user_starred_dashboard) { create(:metrics_users_starred_dashboard, project: project) }
- let_it_be(:other_project_starred_dashboard) { create(:metrics_users_starred_dashboard, user: user) }
-
- context 'without dashboard_path' do
- let(:dashboard_path) { nil }
-
- it 'does not scope user starred dashboards by dashboard path' do
- result = service_instance.execute
-
- expect(result.success?).to be_truthy
- expect(result.payload[:deleted_rows]).to be(2)
- expect(Metrics::UsersStarredDashboard.all).to contain_exactly(other_user_starred_dashboard, other_project_starred_dashboard)
- end
- end
-
- context 'with dashboard_path' do
- let(:dashboard_path) { 'dashboard_1' }
-
- it 'does scope user starred dashboards by dashboard path' do
- result = service_instance.execute
-
- expect(result.success?).to be_truthy
- expect(result.payload[:deleted_rows]).to be(1)
- expect(Metrics::UsersStarredDashboard.all).to contain_exactly(user_starred_dashboard_2, other_user_starred_dashboard, other_project_starred_dashboard)
- end
- end
- end
-end