diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-19 22:11:55 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-19 22:11:55 +0000 |
commit | 5a8431feceba47fd8e1804d9aa1b1730606b71d5 (patch) | |
tree | e5df8e0ceee60f4af8093f5c4c2f934b8abced05 /spec/lib/gitlab/metrics | |
parent | 4d477238500c347c6553d335d920bedfc5a46869 (diff) | |
download | gitlab-ce-5a8431feceba47fd8e1804d9aa1b1730606b71d5.tar.gz |
Add latest changes from gitlab-org/gitlab@12-5-stable-ee
Diffstat (limited to 'spec/lib/gitlab/metrics')
7 files changed, 219 insertions, 75 deletions
diff --git a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb index af5df1fab43..697bedf7362 100644 --- a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb @@ -136,7 +136,7 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi describe '.find_all_paths' do let(:all_dashboard_paths) { described_class.find_all_paths(project) } - let(:system_dashboard) { { path: system_dashboard_path, display_name: 'Default', default: true } } + let(:system_dashboard) { { path: system_dashboard_path, display_name: 'Default', default: true, system_dashboard: true } } it 'includes only the system dashboard by default' do expect(all_dashboard_paths).to eq([system_dashboard]) @@ -147,7 +147,7 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi let(:project) { project_with_dashboard(dashboard_path) } it 'includes system and project dashboards' do - project_dashboard = { path: dashboard_path, display_name: 'test.yml', default: false } + project_dashboard = { path: dashboard_path, display_name: 'test.yml', default: false, system_dashboard: false } expect(all_dashboard_paths).to contain_exactly(system_dashboard, project_dashboard) end diff --git a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb index e2ce1869810..4fa136bc405 100644 --- a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb @@ -25,6 +25,14 @@ describe Gitlab::Metrics::Dashboard::Processor do end end + context 'when the dashboard is not present' do + let(:dashboard_yml) { nil } + + it 'returns nil' do + expect(dashboard).to be_nil + end + end + context 'when dashboard config corresponds to common metrics' do let!(:common_metric) { create(:prometheus_metric, :common, identifier: 'metric_a1') } diff --git a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb index 095d0a2df78..0d4562f78f1 100644 --- a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb @@ -75,6 +75,17 @@ describe Gitlab::Metrics::Dashboard::ServiceSelector do it { is_expected.to be Metrics::Dashboard::CustomMetricEmbedService } end + + context 'with a grafana link' do + let(:arguments) do + { + embedded: true, + grafana_url: 'https://grafana.example.com' + } + end + + it { is_expected.to be Metrics::Dashboard::GrafanaMetricEmbedService } + end end end end diff --git a/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb b/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb new file mode 100644 index 00000000000..5c2ec6dae6b --- /dev/null +++ b/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Metrics::Dashboard::Stages::GrafanaFormatter do + include GrafanaApiHelpers + + let_it_be(:namespace) { create(:namespace, name: 'foo') } + let_it_be(:project) { create(:project, namespace: namespace, name: 'bar') } + + describe '#transform!' do + let(:grafana_dashboard) { JSON.parse(fixture_file('grafana/simplified_dashboard_response.json'), symbolize_names: true) } + let(:datasource) { JSON.parse(fixture_file('grafana/datasource_response.json'), symbolize_names: true) } + + let(:dashboard) { described_class.new(project, {}, params).transform! } + + let(:params) do + { + grafana_dashboard: grafana_dashboard, + datasource: datasource, + grafana_url: valid_grafana_dashboard_link('https://grafana.example.com') + } + end + + context 'when the query and resources are configured correctly' do + let(:expected_dashboard) { JSON.parse(fixture_file('grafana/expected_grafana_embed.json'), symbolize_names: true) } + + it 'generates a gitlab-yml formatted dashboard' do + expect(dashboard).to eq(expected_dashboard) + end + end + + context 'when the inputs are invalid' do + shared_examples_for 'processing error' do + it 'raises a processing error' do + expect { dashboard } + .to raise_error(Gitlab::Metrics::Dashboard::Stages::InputFormatValidator::DashboardProcessingError) + end + end + + context 'when the datasource is not proxyable' do + before do + params[:datasource][:access] = 'not-proxy' + end + + it_behaves_like 'processing error' + end + + context 'when query param "panelId" is not specified' do + before do + params[:grafana_url].gsub!('panelId=8', '') + end + + it_behaves_like 'processing error' + end + + context 'when query param "from" is not specified' do + before do + params[:grafana_url].gsub!('from=1570397739557', '') + end + + it_behaves_like 'processing error' + end + + context 'when query param "to" is not specified' do + before do + params[:grafana_url].gsub!('to=1570484139557', '') + end + + it_behaves_like 'processing error' + end + + context 'when the panel is not a graph' do + before do + params[:grafana_dashboard][:dashboard][:panels][0][:type] = 'singlestat' + end + + it_behaves_like 'processing error' + end + + context 'when the panel is not a line graph' do + before do + params[:grafana_dashboard][:dashboard][:panels][0][:lines] = false + end + + it_behaves_like 'processing error' + end + + context 'when the query dashboard includes undefined variables' do + before do + params[:grafana_url].gsub!('&var-instance=localhost:9121', '') + end + + it_behaves_like 'processing error' + end + + context 'when the expression contains unsupported global variables' do + before do + params[:grafana_dashboard][:dashboard][:panels][0][:targets][0][:expr] = 'sum(important_metric[$__interval_ms])' + end + + it_behaves_like 'processing error' + end + end + end +end diff --git a/spec/lib/gitlab/metrics/dashboard/url_spec.rb b/spec/lib/gitlab/metrics/dashboard/url_spec.rb index e0dc6d98efc..daaf66cba46 100644 --- a/spec/lib/gitlab/metrics/dashboard/url_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/url_spec.rb @@ -3,13 +3,41 @@ require 'spec_helper' describe Gitlab::Metrics::Dashboard::Url do - describe '#regex' do - it 'returns a regular expression' do - expect(described_class.regex).to be_a Regexp - end + shared_examples_for 'a regex which matches the expected url' do + it { is_expected.to be_a Regexp } it 'matches a metrics dashboard link with named params' do - url = Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url( + expect(subject).to match url + + subject.match(url) do |m| + expect(m.named_captures).to eq expected_params + end + end + end + + shared_examples_for 'does not match non-matching urls' do + it 'does not match other gitlab urls that contain the term metrics' do + url = Gitlab::Routing.url_helpers.active_common_namespace_project_prometheus_metrics_url('foo', 'bar', :json) + + expect(subject).not_to match url + end + + it 'does not match other gitlab urls' do + url = Gitlab.config.gitlab.url + + expect(subject).not_to match url + end + + it 'does not match non-gitlab urls' do + url = 'https://www.super_awesome_site.com/' + + expect(subject).not_to match url + end + end + + describe '#regex' do + let(:url) do + Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url( 'foo', 'bar', 1, @@ -18,8 +46,10 @@ describe Gitlab::Metrics::Dashboard::Url do group: 'awesome group', anchor: 'title' ) + end - expected_params = { + let(:expected_params) do + { 'url' => url, 'namespace' => 'foo', 'project' => 'bar', @@ -27,31 +57,40 @@ describe Gitlab::Metrics::Dashboard::Url do 'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z', 'anchor' => '#title' } - - expect(described_class.regex).to match url - - described_class.regex.match(url) do |m| - expect(m.named_captures).to eq expected_params - end end - it 'does not match other gitlab urls that contain the term metrics' do - url = Gitlab::Routing.url_helpers.active_common_namespace_project_prometheus_metrics_url('foo', 'bar', :json) + subject { described_class.regex } - expect(described_class.regex).not_to match url - end + it_behaves_like 'a regex which matches the expected url' + it_behaves_like 'does not match non-matching urls' + end - it 'does not match other gitlab urls' do - url = Gitlab.config.gitlab.url + describe '#grafana_regex' do + let(:url) do + Gitlab::Routing.url_helpers.namespace_project_grafana_api_metrics_dashboard_url( + 'foo', + 'bar', + start: '2019-08-02T05:43:09.000Z', + dashboard: 'config/prometheus/common_metrics.yml', + group: 'awesome group', + anchor: 'title' + ) + end - expect(described_class.regex).not_to match url + let(:expected_params) do + { + 'url' => url, + 'namespace' => 'foo', + 'project' => 'bar', + 'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z', + 'anchor' => '#title' + } end - it 'does not match non-gitlab urls' do - url = 'https://www.super_awesome_site.com/' + subject { described_class.grafana_regex } - expect(described_class.regex).not_to match url - end + it_behaves_like 'a regex which matches the expected url' + it_behaves_like 'does not match non-matching urls' end describe '#build_dashboard_url' do diff --git a/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb index 99349934e63..f22993cf057 100644 --- a/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb +++ b/spec/lib/gitlab/metrics/exporter/web_exporter_spec.rb @@ -4,61 +4,41 @@ require 'spec_helper' describe Gitlab::Metrics::Exporter::WebExporter do let(:exporter) { described_class.new } - - context 'when blackout seconds is used' do - let(:blackout_seconds) { 0 } - let(:readiness_probe) { exporter.send(:readiness_probe).execute } - - before do - stub_config( - monitoring: { - web_exporter: { - enabled: true, - port: 0, - address: '127.0.0.1', - blackout_seconds: blackout_seconds - } + let(:readiness_probe) { exporter.send(:readiness_probe).execute } + + before do + stub_config( + monitoring: { + web_exporter: { + enabled: true, + port: 0, + address: '127.0.0.1' } - ) - - exporter.start - end - - after do - exporter.stop - end + } + ) - context 'when running server' do - it 'readiness probe returns succesful status' do - expect(readiness_probe.http_status).to eq(200) - expect(readiness_probe.json).to include(status: 'ok') - expect(readiness_probe.json).to include('web_exporter' => [{ 'status': 'ok' }]) - end - end - - context 'when blackout seconds is 10s' do - let(:blackout_seconds) { 10 } + exporter.start + end - it 'readiness probe returns a failure status' do - # during sleep we check the status of readiness probe - expect(exporter).to receive(:sleep).with(10) do - expect(readiness_probe.http_status).to eq(503) - expect(readiness_probe.json).to include(status: 'failed') - expect(readiness_probe.json).to include('web_exporter' => [{ 'status': 'failed' }]) - end + after do + exporter.stop + end - exporter.stop - end + context 'when running server' do + it 'readiness probe returns succesful status' do + expect(readiness_probe.http_status).to eq(200) + expect(readiness_probe.json).to include(status: 'ok') + expect(readiness_probe.json).to include('web_exporter' => [{ 'status': 'ok' }]) end + end - context 'when blackout is disabled' do - let(:blackout_seconds) { 0 } - - it 'readiness probe returns a failure status' do - expect(exporter).not_to receive(:sleep) + describe '#mark_as_not_running!' do + it 'readiness probe returns a failure status' do + exporter.mark_as_not_running! - exporter.stop - end + expect(readiness_probe.http_status).to eq(503) + expect(readiness_probe.json).to include(status: 'failed') + expect(readiness_probe.json).to include('web_exporter' => [{ 'status': 'failed' }]) end end end diff --git a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb index f48cd096a98..335670278c4 100644 --- a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb @@ -31,7 +31,7 @@ describe Gitlab::Metrics::RequestsRackMiddleware do end it 'measures execution time' do - expect(described_class).to receive_message_chain(:http_request_duration_seconds, :observe).with({ status: 200, method: 'get' }, a_positive_execution_time) + expect(described_class).to receive_message_chain(:http_request_duration_seconds, :observe).with({ status: '200', method: 'get' }, a_positive_execution_time) Timecop.scale(3600) { subject.call(env) } end @@ -69,7 +69,7 @@ describe Gitlab::Metrics::RequestsRackMiddleware do expected_labels = [] described_class::HTTP_METHODS.each do |method, statuses| statuses.each do |status| - expected_labels << { method: method, status: status.to_i } + expected_labels << { method: method, status: status.to_s } end end |