diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-18 16:16:36 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-18 16:16:36 +0300 |
commit | 311b0269b4eb9839fa63f80c8d7a58f32b8138a0 (patch) | |
tree | 07e7870bca8aed6d61fdcc810731c50d2c40af47 /spec/lib/gitlab/metrics | |
parent | 27909cef6c4170ed9205afa7426b8d3de47cbb0c (diff) |
Add latest changes from gitlab-org/gitlab@14-5-stable-eev14.5.0-rc42
Diffstat (limited to 'spec/lib/gitlab/metrics')
9 files changed, 142 insertions, 347 deletions
diff --git a/spec/lib/gitlab/metrics/background_transaction_spec.rb b/spec/lib/gitlab/metrics/background_transaction_spec.rb index d36ee24fc50..83bee84df99 100644 --- a/spec/lib/gitlab/metrics/background_transaction_spec.rb +++ b/spec/lib/gitlab/metrics/background_transaction_spec.rb @@ -4,27 +4,28 @@ require 'spec_helper' RSpec.describe Gitlab::Metrics::BackgroundTransaction do let(:transaction) { described_class.new } - let(:prometheus_metric) { instance_double(Prometheus::Client::Metric, base_labels: {}) } - - before do - allow(described_class).to receive(:prometheus_metric).and_return(prometheus_metric) - end describe '#run' do + let(:prometheus_metric) { instance_double(Prometheus::Client::Metric, base_labels: {}) } + + before do + allow(described_class).to receive(:prometheus_metric).and_return(prometheus_metric) + end + it 'yields the supplied block' do expect { |b| transaction.run(&b) }.to yield_control end it 'stores the transaction in the current thread' do transaction.run do - expect(Thread.current[described_class::BACKGROUND_THREAD_KEY]).to eq(transaction) + expect(Thread.current[described_class::THREAD_KEY]).to eq(transaction) end end it 'removes the transaction from the current thread upon completion' do transaction.run { } - expect(Thread.current[described_class::BACKGROUND_THREAD_KEY]).to be_nil + expect(Thread.current[described_class::THREAD_KEY]).to be_nil end end @@ -68,7 +69,10 @@ RSpec.describe Gitlab::Metrics::BackgroundTransaction do end end - RSpec.shared_examples 'metric with labels' do |metric_method| + it_behaves_like 'transaction metrics with labels' do + let(:transaction_obj) { described_class.new } + let(:labels) { { endpoint_id: 'TestWorker', feature_category: 'projects', queue: 'test_worker' } } + before do test_worker_class = Class.new do def self.queue @@ -78,33 +82,10 @@ RSpec.describe Gitlab::Metrics::BackgroundTransaction do stub_const('TestWorker', test_worker_class) end - it 'measures with correct labels and value' do - value = 1 - expect(prometheus_metric).to receive(metric_method).with({ - endpoint_id: 'TestWorker', feature_category: 'projects', queue: 'test_worker' - }, value) - + around do |example| Gitlab::ApplicationContext.with_raw_context(feature_category: 'projects', caller_id: 'TestWorker') do - transaction.send(metric_method, :test_metric, value) + example.run end end end - - describe '#increment' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, :increment, base_labels: {}) } - - it_behaves_like 'metric with labels', :increment - end - - describe '#set' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Gauge, :set, base_labels: {}) } - - it_behaves_like 'metric with labels', :set - end - - describe '#observe' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Histogram, :observe, base_labels: {}) } - - it_behaves_like 'metric with labels', :observe - end end diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb index fb5436a90e3..6aa89c7cb05 100644 --- a/spec/lib/gitlab/metrics/method_call_spec.rb +++ b/spec/lib/gitlab/metrics/method_call_spec.rb @@ -37,7 +37,7 @@ RSpec.describe Gitlab::Metrics::MethodCall do it 'metric is not a NullMetric' do method_call.measure { 'foo' } - expect(::Gitlab::Metrics::Transaction.prometheus_metric(:gitlab_method_call_duration_seconds, :histogram)).not_to be_instance_of(Gitlab::Metrics::NullMetric) + expect(::Gitlab::Metrics::WebTransaction.prometheus_metric(:gitlab_method_call_duration_seconds, :histogram)).not_to be_instance_of(Gitlab::Metrics::NullMetric) end it 'observes the performance of the supplied block' do @@ -63,7 +63,7 @@ RSpec.describe Gitlab::Metrics::MethodCall do it 'observes using NullMetric' do method_call.measure { 'foo' } - expect(::Gitlab::Metrics::Transaction.prometheus_metric(:gitlab_method_call_duration_seconds, :histogram)).to be_instance_of(Gitlab::Metrics::NullMetric) + expect(::Gitlab::Metrics::WebTransaction.prometheus_metric(:gitlab_method_call_duration_seconds, :histogram)).to be_instance_of(Gitlab::Metrics::NullMetric) end end end diff --git a/spec/lib/gitlab/metrics/rails_slis_spec.rb b/spec/lib/gitlab/metrics/rails_slis_spec.rb index 16fcb9d46a2..a5ccf7fafa4 100644 --- a/spec/lib/gitlab/metrics/rails_slis_spec.rb +++ b/spec/lib/gitlab/metrics/rails_slis_spec.rb @@ -10,49 +10,62 @@ RSpec.describe Gitlab::Metrics::RailsSlis do allow(Gitlab::RequestEndpoints).to receive(:all_api_endpoints).and_return([api_route]) allow(Gitlab::RequestEndpoints).to receive(:all_controller_actions).and_return([[ProjectsController, 'show']]) + allow(Gitlab::Graphql::KnownOperations).to receive(:default).and_return(Gitlab::Graphql::KnownOperations.new(%w(foo bar))) end describe '.initialize_request_slis_if_needed!' do - it "initializes the SLI for all possible endpoints if they weren't" do + it "initializes the SLI for all possible endpoints if they weren't", :aggregate_failures do possible_labels = [ { endpoint_id: "GET /api/:version/version", - feature_category: :not_owned + feature_category: :not_owned, + request_urgency: :default }, { endpoint_id: "ProjectsController#show", - feature_category: :projects + feature_category: :projects, + request_urgency: :default } ] + possible_graphql_labels = ['graphql:foo', 'graphql:bar', 'graphql:unknown', 'graphql:anonymous'].map do |endpoint_id| + { + endpoint_id: endpoint_id, + feature_category: nil, + query_urgency: ::Gitlab::EndpointAttributes::DEFAULT_URGENCY.name + } + end + expect(Gitlab::Metrics::Sli).to receive(:initialized?).with(:rails_request_apdex) { false } + expect(Gitlab::Metrics::Sli).to receive(:initialized?).with(:graphql_query_apdex) { false } expect(Gitlab::Metrics::Sli).to receive(:initialize_sli).with(:rails_request_apdex, array_including(*possible_labels)).and_call_original + expect(Gitlab::Metrics::Sli).to receive(:initialize_sli).with(:graphql_query_apdex, array_including(*possible_graphql_labels)).and_call_original described_class.initialize_request_slis_if_needed! end - it 'does not initialize the SLI if they were initialized already' do + it 'does not initialize the SLI if they were initialized already', :aggregate_failures do expect(Gitlab::Metrics::Sli).to receive(:initialized?).with(:rails_request_apdex) { true } + expect(Gitlab::Metrics::Sli).to receive(:initialized?).with(:graphql_query_apdex) { true } expect(Gitlab::Metrics::Sli).not_to receive(:initialize_sli) described_class.initialize_request_slis_if_needed! end + end - it 'does not initialize anything if the feature flag is disabled' do - stub_feature_flags(request_apdex_counters: false) - - expect(Gitlab::Metrics::Sli).not_to receive(:initialize_sli) - expect(Gitlab::Metrics::Sli).not_to receive(:initialized?) - + describe '.request_apdex' do + it 'returns the initialized request apdex SLI object' do described_class.initialize_request_slis_if_needed! + + expect(described_class.request_apdex).to be_initialized end end - describe '.request_apdex' do + describe '.graphql_query_apdex' do it 'returns the initialized request apdex SLI object' do described_class.initialize_request_slis_if_needed! - expect(described_class.request_apdex).to be_initialized + expect(described_class.graphql_query_apdex).to be_initialized 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 5870f9a8f68..3396de9b12c 100644 --- a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb @@ -36,7 +36,8 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do it 'tracks request count and duration' do expect(described_class).to receive_message_chain(:http_requests_total, :increment).with(method: 'get', status: '200', feature_category: 'unknown') expect(described_class).to receive_message_chain(:http_request_duration_seconds, :observe).with({ method: 'get' }, a_positive_execution_time) - expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with(labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, success: true) + expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment) + .with(labels: { feature_category: 'unknown', endpoint_id: 'unknown', request_urgency: :default }, success: true) subject.call(env) end @@ -115,14 +116,14 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do context 'application context' do context 'when a context is present' do before do - ::Gitlab::ApplicationContext.push(feature_category: 'issue_tracking', caller_id: 'IssuesController#show') + ::Gitlab::ApplicationContext.push(feature_category: 'team_planning', caller_id: 'IssuesController#show') end it 'adds the feature category to the labels for required metrics' do - expect(described_class).to receive_message_chain(:http_requests_total, :increment).with(method: 'get', status: '200', feature_category: 'issue_tracking') + expect(described_class).to receive_message_chain(:http_requests_total, :increment).with(method: 'get', status: '200', feature_category: 'team_planning') expect(described_class).not_to receive(:http_health_requests_total) expect(Gitlab::Metrics::RailsSlis.request_apdex) - .to receive(:increment).with(labels: { feature_category: 'issue_tracking', endpoint_id: 'IssuesController#show' }, success: true) + .to receive(:increment).with(labels: { feature_category: 'team_planning', endpoint_id: 'IssuesController#show', request_urgency: :default }, success: true) subject.call(env) end @@ -140,12 +141,12 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do context 'when application raises an exception when the feature category context is present' do before do - ::Gitlab::ApplicationContext.push(feature_category: 'issue_tracking') + ::Gitlab::ApplicationContext.push(feature_category: 'team_planning') allow(app).to receive(:call).and_raise(StandardError) end it 'adds the feature category to the labels for http_requests_total' do - expect(described_class).to receive_message_chain(:http_requests_total, :increment).with(method: 'get', status: 'undefined', feature_category: 'issue_tracking') + expect(described_class).to receive_message_chain(:http_requests_total, :increment).with(method: 'get', status: 'undefined', feature_category: 'team_planning') expect(Gitlab::Metrics::RailsSlis).not_to receive(:request_apdex) expect { subject.call(env) }.to raise_error(StandardError) @@ -156,7 +157,8 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do it 'sets the required labels to unknown' do expect(described_class).to receive_message_chain(:http_requests_total, :increment).with(method: 'get', status: '200', feature_category: 'unknown') expect(described_class).not_to receive(:http_health_requests_total) - expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with(labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, success: true) + expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment) + .with(labels: { feature_category: 'unknown', endpoint_id: 'unknown', request_urgency: :default }, success: true) subject.call(env) end @@ -206,7 +208,11 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do it "captures SLI metrics" do expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'hello_world', endpoint_id: 'GET /projects/:id/archive' }, + labels: { + feature_category: 'hello_world', + endpoint_id: 'GET /projects/:id/archive', + request_urgency: request_urgency_name + }, success: success ) subject.call(env) @@ -235,7 +241,11 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do it "captures SLI metrics" do expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'hello_world', endpoint_id: 'AnonymousController#index' }, + labels: { + feature_category: 'hello_world', + endpoint_id: 'AnonymousController#index', + request_urgency: request_urgency_name + }, success: success ) subject.call(env) @@ -255,17 +265,25 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do let(:api_handler) { Class.new(::API::Base) } - it "falls back request's expectation to medium (1 second)" do + it "falls back request's expectation to default (1 second)" do allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(100, 100.9) expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, + labels: { + feature_category: 'unknown', + endpoint_id: 'unknown', + request_urgency: :default + }, success: true ) subject.call(env) allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(100, 101) expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, + labels: { + feature_category: 'unknown', + endpoint_id: 'unknown', + request_urgency: :default + }, success: false ) subject.call(env) @@ -281,17 +299,25 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do { 'action_controller.instance' => controller_instance, 'REQUEST_METHOD' => 'GET' } end - it "falls back request's expectation to medium (1 second)" do + it "falls back request's expectation to default (1 second)" do allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(100, 100.9) expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, + labels: { + feature_category: 'unknown', + endpoint_id: 'unknown', + request_urgency: :default + }, success: true ) subject.call(env) allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(100, 101) expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, + labels: { + feature_category: 'unknown', + endpoint_id: 'unknown', + request_urgency: :default + }, success: false ) subject.call(env) @@ -303,17 +329,25 @@ RSpec.describe Gitlab::Metrics::RequestsRackMiddleware, :aggregate_failures do { 'REQUEST_METHOD' => 'GET' } end - it "falls back request's expectation to medium (1 second)" do + it "falls back request's expectation to default (1 second)" do allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(100, 100.9) expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, + labels: { + feature_category: 'unknown', + endpoint_id: 'unknown', + request_urgency: :default + }, success: true ) subject.call(env) allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(100, 101) expect(Gitlab::Metrics::RailsSlis.request_apdex).to receive(:increment).with( - labels: { feature_category: 'unknown', endpoint_id: 'unknown' }, + labels: { + feature_category: 'unknown', + endpoint_id: 'unknown', + request_urgency: :default + }, success: false ) subject.call(env) diff --git a/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb index f751416f4ec..d834b796179 100644 --- a/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/action_cable_sampler_spec.rb @@ -23,64 +23,46 @@ RSpec.describe Gitlab::Metrics::Samplers::ActionCableSampler do allow(pool).to receive(:queue_length).and_return(6) end - shared_examples 'collects metrics' do |expected_labels| - it 'includes active connections' do - expect(subject.metrics[:active_connections]).to receive(:set).with(expected_labels, 0) + it 'includes active connections' do + expect(subject.metrics[:active_connections]).to receive(:set).with({}, 0) - subject.sample - end - - it 'includes minimum worker pool size' do - expect(subject.metrics[:pool_min_size]).to receive(:set).with(expected_labels, 1) - - subject.sample - end - - it 'includes maximum worker pool size' do - expect(subject.metrics[:pool_max_size]).to receive(:set).with(expected_labels, 2) - - subject.sample - end + subject.sample + end - it 'includes current worker pool size' do - expect(subject.metrics[:pool_current_size]).to receive(:set).with(expected_labels, 3) + it 'includes minimum worker pool size' do + expect(subject.metrics[:pool_min_size]).to receive(:set).with({}, 1) - subject.sample - end + subject.sample + end - it 'includes largest worker pool size' do - expect(subject.metrics[:pool_largest_size]).to receive(:set).with(expected_labels, 4) + it 'includes maximum worker pool size' do + expect(subject.metrics[:pool_max_size]).to receive(:set).with({}, 2) - subject.sample - end + subject.sample + end - it 'includes worker pool completed task count' do - expect(subject.metrics[:pool_completed_tasks]).to receive(:set).with(expected_labels, 5) + it 'includes current worker pool size' do + expect(subject.metrics[:pool_current_size]).to receive(:set).with({}, 3) - subject.sample - end + subject.sample + end - it 'includes worker pool pending task count' do - expect(subject.metrics[:pool_pending_tasks]).to receive(:set).with(expected_labels, 6) + it 'includes largest worker pool size' do + expect(subject.metrics[:pool_largest_size]).to receive(:set).with({}, 4) - subject.sample - end + subject.sample end - context 'for in-app mode' do - before do - expect(Gitlab::ActionCable::Config).to receive(:in_app?).and_return(true) - end + it 'includes worker pool completed task count' do + expect(subject.metrics[:pool_completed_tasks]).to receive(:set).with({}, 5) - it_behaves_like 'collects metrics', server_mode: 'in-app' + subject.sample end - context 'for standalone mode' do - before do - expect(Gitlab::ActionCable::Config).to receive(:in_app?).and_return(false) - end + it 'includes worker pool pending task count' do + expect(subject.metrics[:pool_pending_tasks]).to receive(:set).with({}, 6) - it_behaves_like 'collects metrics', server_mode: 'standalone' + subject.sample end end end diff --git a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb index 7dda10ab41d..e97a4fdddcb 100644 --- a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb @@ -18,8 +18,8 @@ RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do let(:labels) do { class: 'ActiveRecord::Base', - host: Gitlab::Database.main.config['host'], - port: Gitlab::Database.main.config['port'] + host: ApplicationRecord.database.config['host'], + port: ApplicationRecord.database.config['port'] } end diff --git a/spec/lib/gitlab/metrics/subscribers/external_http_spec.rb b/spec/lib/gitlab/metrics/subscribers/external_http_spec.rb index adbc05cb711..e489ac97b9c 100644 --- a/spec/lib/gitlab/metrics/subscribers/external_http_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/external_http_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::Metrics::Subscribers::ExternalHttp, :request_store do - let(:transaction) { Gitlab::Metrics::Transaction.new } + let(:transaction) { Gitlab::Metrics::WebTransaction.new({}) } let(:subscriber) { described_class.new } around do |example| diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb index 2ff8efcd7cb..b1c15db5193 100644 --- a/spec/lib/gitlab/metrics/transaction_spec.rb +++ b/spec/lib/gitlab/metrics/transaction_spec.rb @@ -3,172 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::Metrics::Transaction do - let(:transaction) { described_class.new } - - let(:sensitive_tags) do - { - path: 'private', - branch: 'sensitive' - } - end - - describe '#method_call_for' do - it 'returns a MethodCall' do - method = transaction.method_call_for('Foo#bar', :Foo, '#bar') - - expect(method).to be_an_instance_of(Gitlab::Metrics::MethodCall) - end - end - describe '#run' do - specify { expect { transaction.run }.to raise_error(NotImplementedError) } - end - - describe '#add_event' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, increment: nil, base_labels: {}) } - - it 'adds a metric' do - expect(prometheus_metric).to receive(:increment) - expect(described_class).to receive(:fetch_metric).with(:counter, :gitlab_transaction_event_meow_total).and_return(prometheus_metric) - - transaction.add_event(:meow) - end - - it 'allows tracking of custom tags' do - expect(prometheus_metric).to receive(:increment).with(hash_including(animal: "dog")) - expect(described_class).to receive(:fetch_metric).with(:counter, :gitlab_transaction_event_bau_total).and_return(prometheus_metric) - - transaction.add_event(:bau, animal: 'dog') - end - - context 'with sensitive tags' do - before do - transaction.add_event(:baubau, **sensitive_tags.merge(sane: 'yes')) - allow(described_class).to receive(:prometheus_metric).and_return(prometheus_metric) - end - - it 'filters tags' do - expect(prometheus_metric).not_to receive(:increment).with(hash_including(sensitive_tags)) - - transaction.add_event(:baubau, **sensitive_tags.merge(sane: 'yes')) - end - end - end - - describe '#increment' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, increment: nil, base_labels: {}) } - - it 'adds a metric' do - expect(prometheus_metric).to receive(:increment) - expect(::Gitlab::Metrics).to receive(:counter).with(:meow, 'Meow counter', hash_including(:controller, :action)).and_return(prometheus_metric) - - transaction.increment(:meow, 1) - end - - context 'with block' do - it 'overrides docstring' do - expect(::Gitlab::Metrics).to receive(:counter).with(:block_docstring, 'test', hash_including(:controller, :action)).and_return(prometheus_metric) - - transaction.increment(:block_docstring, 1) do - docstring 'test' - end - end - - it 'overrides labels' do - expect(::Gitlab::Metrics).to receive(:counter).with(:block_labels, 'Block labels counter', hash_including(:controller, :action, :sane)).and_return(prometheus_metric) - - labels = { sane: 'yes' } - transaction.increment(:block_labels, 1, labels) do - label_keys %i(sane) - end - end - - it 'filters sensitive tags' do - expect(::Gitlab::Metrics).to receive(:counter).with(:metric_with_sensitive_block, 'Metric with sensitive block counter', hash_excluding(sensitive_tags)).and_return(prometheus_metric) - - labels_keys = sensitive_tags.keys - transaction.increment(:metric_with_sensitive_block, 1, sensitive_tags) do - label_keys labels_keys - end - end - end - end - - describe '#set' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Gauge, set: nil, base_labels: {}) } - - it 'adds a metric' do - expect(prometheus_metric).to receive(:set) - expect(::Gitlab::Metrics).to receive(:gauge).with(:meow_set, 'Meow set gauge', hash_including(:controller, :action), :all).and_return(prometheus_metric) - - transaction.set(:meow_set, 1) - end - - context 'with block' do - it 'overrides docstring' do - expect(::Gitlab::Metrics).to receive(:gauge).with(:block_docstring_set, 'test', hash_including(:controller, :action), :all).and_return(prometheus_metric) - - transaction.set(:block_docstring_set, 1) do - docstring 'test' - end - end - - it 'overrides labels' do - expect(::Gitlab::Metrics).to receive(:gauge).with(:block_labels_set, 'Block labels set gauge', hash_including(:controller, :action, :sane), :all).and_return(prometheus_metric) - - labels = { sane: 'yes' } - transaction.set(:block_labels_set, 1, labels) do - label_keys %i(sane) - end - end - - it 'filters sensitive tags' do - expect(::Gitlab::Metrics).to receive(:gauge).with(:metric_set_with_sensitive_block, 'Metric set with sensitive block gauge', hash_excluding(sensitive_tags), :all).and_return(prometheus_metric) - - label_keys = sensitive_tags.keys - transaction.set(:metric_set_with_sensitive_block, 1, sensitive_tags) do - label_keys label_keys - end - end - end - end - - describe '#observe' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Histogram, observe: nil, base_labels: {}) } - - it 'adds a metric' do - expect(prometheus_metric).to receive(:observe) - expect(::Gitlab::Metrics).to receive(:histogram).with(:meow_observe, 'Meow observe histogram', hash_including(:controller, :action), kind_of(Array)).and_return(prometheus_metric) - - transaction.observe(:meow_observe, 1) - end - - context 'with block' do - it 'overrides docstring' do - expect(::Gitlab::Metrics).to receive(:histogram).with(:block_docstring_observe, 'test', hash_including(:controller, :action), kind_of(Array)).and_return(prometheus_metric) - - transaction.observe(:block_docstring_observe, 1) do - docstring 'test' - end - end - - it 'overrides labels' do - expect(::Gitlab::Metrics).to receive(:histogram).with(:block_labels_observe, 'Block labels observe histogram', hash_including(:controller, :action, :sane), kind_of(Array)).and_return(prometheus_metric) - - labels = { sane: 'yes' } - transaction.observe(:block_labels_observe, 1, labels) do - label_keys %i(sane) - end - end - - it 'filters sensitive tags' do - expect(::Gitlab::Metrics).to receive(:histogram).with(:metric_observe_with_sensitive_block, 'Metric observe with sensitive block histogram', hash_excluding(sensitive_tags), kind_of(Array)).and_return(prometheus_metric) - - label_keys = sensitive_tags.keys - transaction.observe(:metric_observe_with_sensitive_block, 1, sensitive_tags) do - label_keys label_keys - end - end - end + specify { expect { described_class.new.run }.to raise_error(NotImplementedError) } end end diff --git a/spec/lib/gitlab/metrics/web_transaction_spec.rb b/spec/lib/gitlab/metrics/web_transaction_spec.rb index 9e22dccb2a2..06ce58a9e84 100644 --- a/spec/lib/gitlab/metrics/web_transaction_spec.rb +++ b/spec/lib/gitlab/metrics/web_transaction_spec.rb @@ -5,41 +5,14 @@ require 'spec_helper' RSpec.describe Gitlab::Metrics::WebTransaction do let(:env) { {} } let(:transaction) { described_class.new(env) } - let(:prometheus_metric) { instance_double(Prometheus::Client::Metric, base_labels: {}) } - before do - allow(described_class).to receive(:prometheus_metric).and_return(prometheus_metric) - end - - RSpec.shared_context 'ActionController request' do - let(:request) { double(:request, format: double(:format, ref: :html)) } - let(:controller_class) { double(:controller_class, name: 'TestController') } - - before do - controller = double(:controller, class: controller_class, action_name: 'show', request: request) - env['action_controller.instance'] = controller - end - end + describe '#run' do + let(:prometheus_metric) { instance_double(Prometheus::Client::Metric, base_labels: {}) } - RSpec.shared_context 'transaction observe metrics' do before do + allow(described_class).to receive(:prometheus_metric).and_return(prometheus_metric) allow(transaction).to receive(:observe) end - end - - RSpec.shared_examples 'metric with labels' do |metric_method| - include_context 'ActionController request' - - it 'measures with correct labels and value' do - value = 1 - expect(prometheus_metric).to receive(metric_method).with({ controller: 'TestController', action: 'show', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT }, value) - - transaction.send(metric_method, :bau, value) - end - end - - describe '#run' do - include_context 'transaction observe metrics' it 'yields the supplied block' do expect { |b| transaction.run(&b) }.to yield_control @@ -88,14 +61,6 @@ RSpec.describe Gitlab::Metrics::WebTransaction do end end - describe '#method_call_for' do - it 'returns a MethodCall' do - method = transaction.method_call_for('Foo#bar', :Foo, '#bar') - - expect(method).to be_an_instance_of(Gitlab::Metrics::MethodCall) - end - end - describe '#labels' do context 'when request goes to Grape endpoint' do before do @@ -115,7 +80,7 @@ RSpec.describe Gitlab::Metrics::WebTransaction do end it 'contains only the labels defined for transactions' do - expect(transaction.labels.keys).to contain_exactly(*described_class.superclass::BASE_LABEL_KEYS) + expect(transaction.labels.keys).to contain_exactly(*described_class::BASE_LABEL_KEYS) end it 'does not provide labels if route infos are missing' do @@ -129,14 +94,20 @@ RSpec.describe Gitlab::Metrics::WebTransaction do end context 'when request goes to ActionController' do - include_context 'ActionController request' + let(:request) { double(:request, format: double(:format, ref: :html)) } + let(:controller_class) { double(:controller_class, name: 'TestController') } + + before do + controller = double(:controller, class: controller_class, action_name: 'show', request: request) + env['action_controller.instance'] = controller + end it 'tags a transaction with the name and action of a controller' do expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT }) end it 'contains only the labels defined for transactions' do - expect(transaction.labels.keys).to contain_exactly(*described_class.superclass::BASE_LABEL_KEYS) + expect(transaction.labels.keys).to contain_exactly(*described_class::BASE_LABEL_KEYS) end context 'when the request content type is not :html' do @@ -170,37 +141,16 @@ RSpec.describe Gitlab::Metrics::WebTransaction do end end - describe '#add_event' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, :increment, base_labels: {}) } - - it 'adds a metric' do - expect(prometheus_metric).to receive(:increment) - - transaction.add_event(:meow) - end + it_behaves_like 'transaction metrics with labels' do + let(:request) { double(:request, format: double(:format, ref: :html)) } + let(:controller_class) { double(:controller_class, name: 'TestController') } + let(:controller) { double(:controller, class: controller_class, action_name: 'show', request: request) } - it 'allows tracking of custom tags' do - expect(prometheus_metric).to receive(:increment).with(animal: "dog") + let(:transaction_obj) { described_class.new({ 'action_controller.instance' => controller }) } + let(:labels) { { controller: 'TestController', action: 'show', feature_category: 'projects' } } - transaction.add_event(:bau, animal: 'dog') + before do + ::Gitlab::ApplicationContext.push(feature_category: 'projects') end end - - describe '#increment' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, :increment, base_labels: {}) } - - it_behaves_like 'metric with labels', :increment - end - - describe '#set' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Gauge, :set, base_labels: {}) } - - it_behaves_like 'metric with labels', :set - end - - describe '#observe' do - let(:prometheus_metric) { instance_double(Prometheus::Client::Histogram, :observe, base_labels: {}) } - - it_behaves_like 'metric with labels', :observe - end end |