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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 04:45:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 04:45:44 +0300
commit85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch)
tree9160f299afd8c80c038f08e1545be119f5e3f1e1 /spec/lib/gitlab/metrics/dashboard
parent15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff)
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'spec/lib/gitlab/metrics/dashboard')
-rw-r--r--spec/lib/gitlab/metrics/dashboard/importer_spec.rb55
-rw-r--r--spec/lib/gitlab/metrics/dashboard/importers/prometheus_metrics_spec.rb79
-rw-r--r--spec/lib/gitlab/metrics/dashboard/stages/track_panel_type_spec.rb13
-rw-r--r--spec/lib/gitlab/metrics/dashboard/transformers/yml/v1/prometheus_metrics_spec.rb99
-rw-r--r--spec/lib/gitlab/metrics/dashboard/url_spec.rb103
-rw-r--r--spec/lib/gitlab/metrics/dashboard/validator/errors_spec.rb13
-rw-r--r--spec/lib/gitlab/metrics/dashboard/validator_spec.rb52
7 files changed, 390 insertions, 24 deletions
diff --git a/spec/lib/gitlab/metrics/dashboard/importer_spec.rb b/spec/lib/gitlab/metrics/dashboard/importer_spec.rb
new file mode 100644
index 00000000000..8b705395a2c
--- /dev/null
+++ b/spec/lib/gitlab/metrics/dashboard/importer_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Metrics::Dashboard::Importer do
+ include MetricsDashboardHelpers
+
+ let_it_be(:dashboard_path) { '.gitlab/dashboards/sample_dashboard.yml' }
+ let_it_be(:project) { create(:project) }
+
+ before do
+ allow(subject).to receive(:dashboard_hash).and_return(dashboard_hash)
+ end
+
+ subject { described_class.new(dashboard_path, project) }
+
+ describe '.execute' do
+ context 'valid dashboard hash' do
+ let(:dashboard_hash) { load_sample_dashboard }
+
+ it 'imports metrics to database' do
+ expect { subject.execute }
+ .to change { PrometheusMetric.count }.from(0).to(3)
+ end
+ end
+
+ context 'invalid dashboard hash' do
+ let(:dashboard_hash) { {} }
+
+ it 'returns false' do
+ expect(subject.execute).to be(false)
+ end
+ end
+ end
+
+ describe '.execute!' do
+ context 'valid dashboard hash' do
+ let(:dashboard_hash) { load_sample_dashboard }
+
+ it 'imports metrics to database' do
+ expect { subject.execute }
+ .to change { PrometheusMetric.count }.from(0).to(3)
+ end
+ end
+
+ context 'invalid dashboard hash' do
+ let(:dashboard_hash) { {} }
+
+ it 'raises error' do
+ expect { subject.execute! }.to raise_error(Gitlab::Metrics::Dashboard::Validator::Errors::SchemaValidationError,
+ 'root is missing required keys: dashboard, panel_groups')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/dashboard/importers/prometheus_metrics_spec.rb b/spec/lib/gitlab/metrics/dashboard/importers/prometheus_metrics_spec.rb
new file mode 100644
index 00000000000..09d5e048f6a
--- /dev/null
+++ b/spec/lib/gitlab/metrics/dashboard/importers/prometheus_metrics_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Metrics::Dashboard::Importers::PrometheusMetrics do
+ include MetricsDashboardHelpers
+
+ describe '#execute' do
+ let(:project) { create(:project) }
+ let(:dashboard_path) { 'path/to/dashboard.yml' }
+
+ subject { described_class.new(dashboard_hash, project: project, dashboard_path: dashboard_path) }
+
+ context 'valid dashboard' do
+ let(:dashboard_hash) { load_sample_dashboard }
+
+ context 'with all new metrics' do
+ it 'creates PrometheusMetrics' do
+ expect { subject.execute }.to change { PrometheusMetric.count }.by(3)
+ end
+ end
+
+ context 'with existing metrics' do
+ let!(:existing_metric) do
+ create(:prometheus_metric, {
+ project: project,
+ identifier: 'metric_b',
+ title: 'overwrite',
+ y_label: 'overwrite',
+ query: 'overwrite',
+ unit: 'overwrite',
+ legend: 'overwrite'
+ })
+ end
+
+ it 'updates existing PrometheusMetrics' do
+ described_class.new(dashboard_hash, project: project, dashboard_path: dashboard_path).execute
+
+ expect(existing_metric.reload.attributes.with_indifferent_access).to include({
+ title: 'Super Chart B',
+ y_label: 'y_label',
+ query: 'query',
+ unit: 'unit',
+ legend: 'Legend Label'
+ })
+ end
+
+ it 'creates new PrometheusMetrics' do
+ expect { subject.execute }.to change { PrometheusMetric.count }.by(2)
+ end
+
+ context 'with stale metrics' do
+ let!(:stale_metric) do
+ create(:prometheus_metric,
+ project: project,
+ identifier: 'stale_metric',
+ dashboard_path: dashboard_path,
+ group: 3
+ )
+ end
+
+ it 'deletes stale metrics' do
+ subject.execute
+
+ expect { stale_metric.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+ end
+
+ context 'invalid dashboard' do
+ let(:dashboard_hash) { {} }
+
+ it 'returns false' do
+ expect(subject.execute).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/dashboard/stages/track_panel_type_spec.rb b/spec/lib/gitlab/metrics/dashboard/stages/track_panel_type_spec.rb
index d9987b67127..60010b9f257 100644
--- a/spec/lib/gitlab/metrics/dashboard/stages/track_panel_type_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/stages/track_panel_type_spec.rb
@@ -8,20 +8,19 @@ RSpec.describe Gitlab::Metrics::Dashboard::Stages::TrackPanelType do
let(:project) { build_stubbed(:project) }
let(:environment) { build_stubbed(:environment, project: project) }
- describe '#transform!' do
+ describe '#transform!', :snowplow do
subject { described_class.new(project, dashboard, environment: environment) }
let(:dashboard) { load_sample_dashboard.deep_symbolize_keys }
it 'creates tracking event' do
- stub_application_setting(snowplow_enabled: true, snowplow_collector_hostname: 'localhost')
- allow(Gitlab::Tracking).to receive(:event).and_call_original
-
subject.transform!
- expect(Gitlab::Tracking).to have_received(:event)
- .with('MetricsDashboard::Chart', 'chart_rendered', { label: 'area-chart' })
- .at_least(:once)
+ expect_snowplow_event(
+ category: 'MetricsDashboard::Chart',
+ action: 'chart_rendered',
+ label: 'area-chart'
+ )
end
end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/transformers/yml/v1/prometheus_metrics_spec.rb b/spec/lib/gitlab/metrics/dashboard/transformers/yml/v1/prometheus_metrics_spec.rb
new file mode 100644
index 00000000000..3af8b51c889
--- /dev/null
+++ b/spec/lib/gitlab/metrics/dashboard/transformers/yml/v1/prometheus_metrics_spec.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Metrics::Dashboard::Transformers::Yml::V1::PrometheusMetrics do
+ include MetricsDashboardHelpers
+
+ describe '#execute' do
+ subject { described_class.new(dashboard_hash) }
+
+ context 'valid dashboard' do
+ let_it_be(:dashboard_hash) do
+ {
+ panel_groups: [{
+ panels: [
+ {
+ title: 'Panel 1 title',
+ y_label: 'Panel 1 y_label',
+ metrics: [
+ {
+ query_range: 'Panel 1 metric 1 query_range',
+ unit: 'Panel 1 metric 1 unit',
+ label: 'Panel 1 metric 1 label',
+ id: 'Panel 1 metric 1 id'
+ },
+ {
+ query: 'Panel 1 metric 2 query',
+ unit: 'Panel 1 metric 2 unit',
+ label: 'Panel 1 metric 2 label',
+ id: 'Panel 1 metric 2 id'
+ }
+ ]
+ },
+ {
+ title: 'Panel 2 title',
+ y_label: 'Panel 2 y_label',
+ metrics: [{
+ query_range: 'Panel 2 metric 1 query_range',
+ unit: 'Panel 2 metric 1 unit',
+ label: 'Panel 2 metric 1 label',
+ id: 'Panel 2 metric 1 id'
+ }]
+ }
+ ]
+ }]
+ }
+ end
+
+ let(:expected_metrics) do
+ [
+ {
+ title: 'Panel 1 title',
+ y_label: 'Panel 1 y_label',
+ query: "Panel 1 metric 1 query_range",
+ unit: 'Panel 1 metric 1 unit',
+ legend: 'Panel 1 metric 1 label',
+ identifier: 'Panel 1 metric 1 id',
+ group: 3,
+ common: false
+ },
+ {
+ title: 'Panel 1 title',
+ y_label: 'Panel 1 y_label',
+ query: 'Panel 1 metric 2 query',
+ unit: 'Panel 1 metric 2 unit',
+ legend: 'Panel 1 metric 2 label',
+ identifier: 'Panel 1 metric 2 id',
+ group: 3,
+ common: false
+ },
+ {
+ title: 'Panel 2 title',
+ y_label: 'Panel 2 y_label',
+ query: 'Panel 2 metric 1 query_range',
+ unit: 'Panel 2 metric 1 unit',
+ legend: 'Panel 2 metric 1 label',
+ identifier: 'Panel 2 metric 1 id',
+ group: 3,
+ common: false
+ }
+ ]
+ end
+
+ it 'returns collection of metrics with correct attributes' do
+ expect(subject.execute).to match_array(expected_metrics)
+ end
+ end
+
+ context 'invalid dashboard' do
+ let(:dashboard_hash) { {} }
+
+ it 'raises missing attribute error' do
+ expect { subject.execute }.to raise_error(
+ ::Gitlab::Metrics::Dashboard::Transformers::Errors::MissingAttribute, "Missing attribute: 'panel_groups'"
+ )
+ 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 205e1000376..830d43169a9 100644
--- a/spec/lib/gitlab/metrics/dashboard/url_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
@@ -6,11 +6,12 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
include Gitlab::Routing.url_helpers
describe '#metrics_regex' do
+ let(:environment_id) { 1 }
let(:url_params) do
[
'foo',
'bar',
- 1,
+ environment_id,
{
start: '2019-08-02T05:43:09.000Z',
dashboard: 'config/prometheus/common_metrics.yml',
@@ -33,12 +34,42 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.metrics_regex }
- context 'for metrics route' do
+ context 'for /-/environments/:environment_id/metrics route' do
let(:url) { metrics_namespace_project_environment_url(*url_params) }
it_behaves_like 'regex which matches url when expected'
end
+ context 'for /-/metrics?environment=:environment_id route' do
+ let(:url) { namespace_project_metrics_dashboard_url(*url_params) }
+ let(:url_params) do
+ [
+ 'namespace1',
+ 'project1',
+ {
+ environment: environment_id,
+ start: '2019-08-02T05:43:09.000Z',
+ dashboard: 'config/prometheus/common_metrics.yml',
+ group: 'awesome group',
+ anchor: 'title'
+ }
+ ]
+ end
+
+ let(:expected_params) do
+ {
+ 'url' => url,
+ 'namespace' => 'namespace1',
+ 'project' => 'project1',
+ 'environment' => "#{environment_id}",
+ 'query' => "?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&environment=#{environment_id}&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z",
+ 'anchor' => '#title'
+ }
+ end
+
+ it_behaves_like 'regex which matches url when expected'
+ end
+
context 'for metrics_dashboard route' do
let(:url) { metrics_dashboard_namespace_project_environment_url(*url_params) }
@@ -47,16 +78,19 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
end
describe '#clusters_regex' do
- let(:url) do
- Gitlab::Routing.url_helpers.namespace_project_cluster_url(
+ let(:url) { Gitlab::Routing.url_helpers.namespace_project_cluster_url(*url_params) }
+ let(:url_params) do
+ [
'foo',
'bar',
'1',
- group: 'Cluster Health',
- title: 'Memory Usage',
- y_label: 'Memory 20(GiB)',
- anchor: 'title'
- )
+ {
+ group: 'Cluster Health',
+ title: 'Memory Usage',
+ y_label: 'Memory 20(GiB)',
+ anchor: 'title'
+ }
+ ]
end
let(:expected_params) do
@@ -73,6 +107,27 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.clusters_regex }
it_behaves_like 'regex which matches url when expected'
+
+ context 'for metrics_dashboard route' do
+ let(:url) do
+ metrics_dashboard_namespace_project_cluster_url(
+ *url_params, cluster_type: :project, embedded: true, format: :json
+ )
+ end
+
+ let(:expected_params) do
+ {
+ 'url' => url,
+ 'namespace' => 'foo',
+ 'project' => 'bar',
+ 'cluster_id' => '1',
+ 'query' => '?cluster_type=project&embedded=true',
+ 'anchor' => nil
+ }
+ end
+
+ it_behaves_like 'regex which matches url when expected'
+ end
end
describe '#grafana_regex' do
@@ -103,15 +158,18 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
end
describe '#alert_regex' do
- let(:url) do
- Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_prometheus_alert_url(
+ let(:url) { Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_prometheus_alert_url(*url_params) }
+ let(:url_params) do
+ [
'foo',
'bar',
'1',
- start: '2020-02-10T12:59:49.938Z',
- end: '2020-02-10T20:59:49.938Z',
- anchor: "anchor"
- )
+ {
+ start: '2020-02-10T12:59:49.938Z',
+ end: '2020-02-10T20:59:49.938Z',
+ anchor: "anchor"
+ }
+ ]
end
let(:expected_params) do
@@ -128,6 +186,21 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.alert_regex }
it_behaves_like 'regex which matches url when expected'
+
+ it_behaves_like 'regex which matches url when expected' do
+ let(:url) { Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_prometheus_alert_url(*url_params, format: :json) }
+
+ let(:expected_params) do
+ {
+ 'url' => url,
+ 'namespace' => 'foo',
+ 'project' => 'bar',
+ 'alert' => '1',
+ 'query' => nil,
+ 'anchor' => nil
+ }
+ end
+ end
end
describe '#build_dashboard_url' do
diff --git a/spec/lib/gitlab/metrics/dashboard/validator/errors_spec.rb b/spec/lib/gitlab/metrics/dashboard/validator/errors_spec.rb
index f0db1bd0d33..fdbba6c31b5 100644
--- a/spec/lib/gitlab/metrics/dashboard/validator/errors_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/validator/errors_spec.rb
@@ -34,6 +34,17 @@ RSpec.describe Gitlab::Metrics::Dashboard::Validator::Errors do
it { is_expected.to eq 'root is missing required keys: one' }
end
+
+ context 'when there is type mismatch' do
+ %w(null string boolean integer number array object).each do |expected_type|
+ context "on type: #{expected_type}" do
+ let(:type) { expected_type }
+ let(:details) { nil }
+
+ it { is_expected.to eq "'property_name' at root is not of type: #{expected_type}" }
+ end
+ end
+ end
end
context 'for nested object' do
@@ -52,8 +63,6 @@ RSpec.describe Gitlab::Metrics::Dashboard::Validator::Errors do
let(:type) { expected_type }
let(:details) { nil }
- subject { described_class.new(error_hash).message }
-
it { is_expected.to eq "'property_name' at /nested_objects/0 is not of type: #{expected_type}" }
end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/validator_spec.rb b/spec/lib/gitlab/metrics/dashboard/validator_spec.rb
index c4cda271408..eb67ea2b7da 100644
--- a/spec/lib/gitlab/metrics/dashboard/validator_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/validator_spec.rb
@@ -143,4 +143,56 @@ RSpec.describe Gitlab::Metrics::Dashboard::Validator do
end
end
end
+
+ describe '#errors' do
+ context 'valid dashboard schema' do
+ it 'returns no errors' do
+ expect(described_class.errors(valid_dashboard)).to eq []
+ end
+
+ context 'with duplicate metric_ids' do
+ it 'returns errors' do
+ expect(described_class.errors(duplicate_id_dashboard)).to eq [Gitlab::Metrics::Dashboard::Validator::Errors::DuplicateMetricIds.new]
+ end
+ end
+
+ context 'with dashboard_path and project' do
+ subject { described_class.errors(valid_dashboard, dashboard_path: 'test/path.yml', project: project) }
+
+ context 'with no conflicting metric identifiers in db' do
+ it { is_expected.to eq [] }
+ end
+
+ context 'with metric identifier present in current dashboard' do
+ before do
+ create(:prometheus_metric,
+ identifier: 'metric_a1',
+ dashboard_path: 'test/path.yml',
+ project: project
+ )
+ end
+
+ it { is_expected.to eq [] }
+ end
+
+ context 'with metric identifier present in another dashboard' do
+ before do
+ create(:prometheus_metric,
+ identifier: 'metric_a1',
+ dashboard_path: 'some/other/dashboard/path.yml',
+ project: project
+ )
+ end
+
+ it { is_expected.to eq [Gitlab::Metrics::Dashboard::Validator::Errors::DuplicateMetricIds.new] }
+ end
+ end
+ end
+
+ context 'invalid dashboard schema' do
+ it 'returns collection of validation errors' do
+ expect(described_class.errors(invalid_dashboard)).to all be_kind_of(Gitlab::Metrics::Dashboard::Validator::Errors::SchemaValidationError)
+ end
+ end
+ end
end