diff options
author | Sarah Yasonik <syasonik@gitlab.com> | 2019-08-07 19:17:35 +0300 |
---|---|---|
committer | Sean McGivern <sean@gitlab.com> | 2019-08-07 19:17:35 +0300 |
commit | bf918b68f643266e91a9308cbc64a8304c647f17 (patch) | |
tree | ddface6092de44fafe2e0929158fc65d92766f47 /spec/services/metrics | |
parent | d8966abd20c860d2f30141f3647f2b81f70b683d (diff) |
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.rb | 145 | ||||
-rw-r--r-- | spec/services/metrics/dashboard/dynamic_embed_service_spec.rb | 151 |
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 |