summaryrefslogtreecommitdiff
path: root/spec/services/metrics
diff options
context:
space:
mode:
authorSarah Yasonik <syasonik@gitlab.com>2019-08-07 16:17:35 +0000
committerSean McGivern <sean@gitlab.com>2019-08-07 16:17:35 +0000
commitbf918b68f643266e91a9308cbc64a8304c647f17 (patch)
treeddface6092de44fafe2e0929158fc65d92766f47 /spec/services/metrics
parentd8966abd20c860d2f30141f3647f2b81f70b683d (diff)
downloadgitlab-ce-bf918b68f643266e91a9308cbc64a8304c647f17.tar.gz
Support dashboard params for metrics dashboard
https://gitlab.com/gitlab-org/gitlab-ce/issues/62971 Adds support to EnvironmentsController#metrics_dashboard for the following params: group, title, y_label These params are used to uniquely identify a panel on the metrics dashboard. Metrics are stored in several places, so this adds utilities to find a specific panel from the database or filesystem depending on the metric specified. Also moves some shared utilities into separate classes, notably default values and errors.
Diffstat (limited to 'spec/services/metrics')
-rw-r--r--spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb145
-rw-r--r--spec/services/metrics/dashboard/dynamic_embed_service_spec.rb151
2 files changed, 296 insertions, 0 deletions
diff --git a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
new file mode 100644
index 00000000000..53b7497ae21
--- /dev/null
+++ b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
@@ -0,0 +1,145 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Metrics::Dashboard::CustomMetricEmbedService do
+ include MetricsDashboardHelpers
+
+ set(:project) { build(:project) }
+ set(:user) { create(:user) }
+ set(:environment) { create(:environment, project: project) }
+
+ before do
+ project.add_maintainer(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 'not embedded' do
+ let(:params) { valid_params.except(:embedded) }
+
+ 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
+ expect(Gitlab::Metrics::Dashboard::Cache).not_to receive(:fetch)
+
+ 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' do
+ result = service_call
+ included_queries = all_queries(result[:dashboard])
+
+ expect(included_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
+
+ private
+
+ def all_queries(dashboard)
+ dashboard[:panel_groups].flat_map do |group|
+ group[:panels].flat_map do |panel|
+ panel[:metrics].map do |metric|
+ metric[:query_range]
+ end
+ end
+ 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
new file mode 100644
index 00000000000..a0f7315f750
--- /dev/null
+++ b/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb
@@ -0,0 +1,151 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Metrics::Dashboard::DynamicEmbedService, :use_clean_rails_memory_store_caching do
+ include MetricsDashboardHelpers
+
+ set(:project) { build(:project) }
+ set(:user) { create(:user) }
+ set(:environment) { create(:environment, project: project) }
+
+ before do
+ project.add_maintainer(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 'not embedded' do
+ let(:params) { valid_params.except(:embedded) }
+
+ 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 default 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