diff options
Diffstat (limited to 'spec/lib/gitlab/usage')
17 files changed, 457 insertions, 145 deletions
diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb index 08adc031631..fb46d48c1bb 100644 --- a/spec/lib/gitlab/usage/metric_definition_spec.rb +++ b/spec/lib/gitlab/usage/metric_definition_spec.rb @@ -46,6 +46,34 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping end end + describe '.instrumentation_class' do + context 'for non internal events' do + let(:attributes) { { key_path: 'metric1', instrumentation_class: 'RedisHLLMetric', data_source: 'redis_hll' } } + + it 'returns class from the definition' do + expect(definition.instrumentation_class).to eq('RedisHLLMetric') + end + end + + context 'for internal events' do + context 'for total counter' do + let(:attributes) { { key_path: 'metric1', data_source: 'internal_events', events: [{ name: 'a' }] } } + + it 'returns TotalCounterMetric' do + expect(definition.instrumentation_class).to eq('TotalCountMetric') + end + end + + context 'for uniq counter' do + let(:attributes) { { key_path: 'metric1', data_source: 'internal_events', events: [{ name: 'a', unique: :id }] } } + + it 'returns RedisHLLMetric' do + expect(definition.instrumentation_class).to eq('RedisHLLMetric') + end + end + end + end + describe 'not_removed' do let(:all_definitions) do metrics_definitions = [ @@ -71,12 +99,13 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping describe '#with_instrumentation_class' do let(:all_definitions) do metrics_definitions = [ - { key_path: 'metric1', instrumentation_class: 'RedisHLLMetric', status: 'active' }, - { key_path: 'metric2', instrumentation_class: 'RedisHLLMetric', status: 'broken' }, - { key_path: 'metric3', instrumentation_class: 'RedisHLLMetric', status: 'active' }, - { key_path: 'metric4', instrumentation_class: 'RedisHLLMetric', status: 'removed' }, - { key_path: 'metric5', status: 'active' }, - { key_path: 'metric_missing_status' } + { key_path: 'metric1', status: 'active', data_source: 'redis_hll', instrumentation_class: 'RedisHLLMetric' }, + { key_path: 'metric2', status: 'active', data_source: 'internal_events' }, # class is defined by data_source + + { key_path: 'metric3', status: 'active', data_source: 'redis_hll' }, + { key_path: 'metric4', status: 'removed', instrumentation_class: 'RedisHLLMetric', data_source: 'redis_hll' }, + { key_path: 'metric5', status: 'removed', data_source: 'internal_events' }, + { key_path: 'metric_missing_status', data_source: 'internal_events' } ] metrics_definitions.map { |definition| described_class.new(definition[:key_path], definition.symbolize_keys) } end @@ -86,15 +115,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping end it 'includes definitions with instrumentation_class' do - expect(described_class.with_instrumentation_class.count).to eq(3) - end - - context 'with removed metric' do - let(:metric_status) { 'removed' } - - it 'excludes removed definitions' do - expect(described_class.with_instrumentation_class.count).to eq(3) - end + expect(described_class.with_instrumentation_class.map(&:key_path)).to match_array(%w[metric1 metric2]) end end @@ -224,25 +245,9 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping where(:instrumentation_class, :options, :events, :is_valid) do 'AnotherClass' | { events: ['a'] } | [{ name: 'a', unique: 'user.id' }] | false - nil | { events: ['a'] } | [{ name: 'a', unique: 'user.id' }] | false - 'RedisHLLMetric' | { events: ['a'] } | [{ name: 'a', unique: 'user.id' }] | true + 'RedisHLLMetric' | { events: ['a'] } | [{ name: 'a', unique: 'user.id' }] | false 'RedisHLLMetric' | { events: ['a'] } | nil | false - 'RedisHLLMetric' | nil | [{ name: 'a', unique: 'user.id' }] | false - 'RedisHLLMetric' | { events: ['a'] } | [{ name: 'a', unique: 'a' }] | false - 'RedisHLLMetric' | { events: 'a' } | [{ name: 'a', unique: 'user.id' }] | false - 'RedisHLLMetric' | { events: [2] } | [{ name: 'a', unique: 'user.id' }] | false - 'RedisHLLMetric' | { events: ['a'], a: 'b' } | [{ name: 'a', unique: 'user.id' }] | false - 'RedisHLLMetric' | { events: ['a'] } | [{ name: 'a', unique: 'user.id', b: 'c' }] | false - 'RedisHLLMetric' | { events: ['a'] } | [{ name: 'a' }] | false - 'RedisHLLMetric' | { events: ['a'] } | [{ unique: 'user.id' }] | false - 'TotalCountMetric' | { events: ['a'] } | [{ name: 'a' }] | true - 'TotalCountMetric' | { events: ['a'] } | [{ name: 'a', unique: 'user.id' }] | false - 'TotalCountMetric' | { events: ['a'] } | nil | false - 'TotalCountMetric' | nil | [{ name: 'a' }] | false - 'TotalCountMetric' | { events: [2] } | [{ name: 'a' }] | false - 'TotalCountMetric' | { events: ['a'] } | [{}] | false - 'TotalCountMetric' | 'a' | [{ name: 'a' }] | false - 'TotalCountMetric' | { events: ['a'], a: 'b' } | [{ name: 'a' }] | false + nil | { events: ['a'] } | [{ name: 'a', unique: 'user.id' }] | true end with_them do diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/bulk_imports_users_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/bulk_imports_users_metric_spec.rb new file mode 100644 index 00000000000..90791bf223f --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/bulk_imports_users_metric_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::BulkImportsUsersMetric, feature_category: :importers do + let(:expected_value) { 3 } + let(:expected_query) { "SELECT COUNT(DISTINCT \"bulk_imports\".\"user_id\") FROM \"bulk_imports\"" } + + before_all do + import = create :bulk_import, created_at: 3.days.ago + create :bulk_import, created_at: 35.days.ago + create :bulk_import, created_at: 3.days.ago + create :bulk_import, created_at: 3.days.ago, user: import.user + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' } do + let(:expected_value) { 2 } + let(:start) { 30.days.ago.to_fs(:db) } + let(:finish) { 2.days.ago.to_fs(:db) } + let(:expected_query) do + "SELECT COUNT(DISTINCT \"bulk_imports\".\"user_id\") FROM \"bulk_imports\" " \ + "WHERE \"bulk_imports\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'" + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_service_desk_custom_email_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_service_desk_custom_email_enabled_metric_spec.rb new file mode 100644 index 00000000000..6d10052ff66 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_service_desk_custom_email_enabled_metric_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountServiceDeskCustomEmailEnabledMetric, feature_category: :service_ping do + let_it_be(:project) { create(:project) } + let_it_be(:credential) { create(:service_desk_custom_email_credential, project: project) } + let_it_be(:verification) { create(:service_desk_custom_email_verification, :finished, project: project) } + let_it_be(:setting) do + create(:service_desk_setting, project: project, custom_email: 'support@example.com', custom_email_enabled: true) + end + + let(:expected_value) { 1 } + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/csv_imports_users_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/csv_imports_users_metric_spec.rb new file mode 100644 index 00000000000..1f620c2502d --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/csv_imports_users_metric_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CsvImportsUsersMetric, feature_category: :importers do + let(:expected_value) { 3 } + let(:expected_query) { "SELECT COUNT(DISTINCT \"csv_issue_imports\".\"user_id\") FROM \"csv_issue_imports\"" } + + before_all do + import = create :issue_csv_import, created_at: 3.days.ago + create :issue_csv_import, created_at: 35.days.ago + create :issue_csv_import, created_at: 3.days.ago + create :issue_csv_import, created_at: 3.days.ago, user: import.user + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' } do + let(:expected_value) { 2 } + let(:start) { 30.days.ago.to_fs(:db) } + let(:finish) { 2.days.ago.to_fs(:db) } + let(:expected_query) do + "SELECT COUNT(DISTINCT \"csv_issue_imports\".\"user_id\") FROM \"csv_issue_imports\" " \ + "WHERE \"csv_issue_imports\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'" + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/gitlab_config_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/gitlab_config_metric_spec.rb new file mode 100644 index 00000000000..e9814f0cb51 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/gitlab_config_metric_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GitlabConfigMetric, feature_category: :service_ping do + describe 'config metric' do + using RSpec::Parameterized::TableSyntax + + where(:config_value, :expected_value) do + false | false + true | true + end + + with_them do + before do + stub_config(artifacts: { object_store: { enabled: config_value } }) + end + + it_behaves_like 'a correct instrumented metric value', { + time_frame: 'none', + options: { + config: { + artifacts: { + object_store: 'enabled' + } + } + } + } + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/gitlab_settings_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/gitlab_settings_metric_spec.rb new file mode 100644 index 00000000000..26210b9febf --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/gitlab_settings_metric_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GitlabSettingsMetric, feature_category: :service_ping do + describe 'settings metric' do + using RSpec::Parameterized::TableSyntax + + where(:setting_value, :expected_value) do + false | false + true | true + end + + with_them do + before do + stub_application_setting(gravatar_enabled: setting_value) + end + + it_behaves_like 'a correct instrumented metric value', { + time_frame: 'none', + options: { + setting_method: 'gravatar_enabled' + } + } + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/group_imports_users_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/group_imports_users_metric_spec.rb new file mode 100644 index 00000000000..6b7962fda64 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/group_imports_users_metric_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::GroupImportsUsersMetric, feature_category: :importers do + let(:expected_value) { 3 } + let(:expected_query) { "SELECT COUNT(DISTINCT \"group_import_states\".\"user_id\") FROM \"group_import_states\"" } + + before_all do + import = create :group_import_state, created_at: 3.days.ago + create :group_import_state, created_at: 35.days.ago + create :group_import_state, created_at: 3.days.ago + create :group_import_state, created_at: 3.days.ago, user: import.user + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' } do + let(:expected_value) { 2 } + let(:start) { 30.days.ago.to_fs(:db) } + let(:finish) { 2.days.ago.to_fs(:db) } + let(:expected_query) do + "SELECT COUNT(DISTINCT \"group_import_states\".\"user_id\") FROM \"group_import_states\" " \ + "WHERE \"group_import_states\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'" + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/in_product_marketing_email_cta_clicked_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/in_product_marketing_email_cta_clicked_metric_spec.rb deleted file mode 100644 index 91ad81c4291..00000000000 --- a/spec/lib/gitlab/usage/metrics/instrumentations/in_product_marketing_email_cta_clicked_metric_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Usage::Metrics::Instrumentations::InProductMarketingEmailCtaClickedMetric do - using RSpec::Parameterized::TableSyntax - - let(:email_attributes) { { cta_clicked_at: Date.yesterday, track: 'verify', series: 0 } } - let(:options) { { track: 'verify', series: 0 } } - let(:expected_value) { 2 } - let(:expected_query) do - 'SELECT COUNT("in_product_marketing_emails"."id") FROM "in_product_marketing_emails" ' \ - 'WHERE "in_product_marketing_emails"."cta_clicked_at" IS NOT NULL ' \ - 'AND "in_product_marketing_emails"."series" = 0 ' \ - 'AND "in_product_marketing_emails"."track" = 1' - end - - before do - create_list :in_product_marketing_email, 2, email_attributes - - create :in_product_marketing_email, email_attributes.merge(cta_clicked_at: nil) - create :in_product_marketing_email, email_attributes.merge(track: 'team') - create :in_product_marketing_email, email_attributes.merge(series: 1) - end - - it_behaves_like 'a correct instrumented metric value and query', { - options: { track: 'verify', series: 0 }, - time_frame: 'all' - } - - where(:options_key, :valid_value, :invalid_value) do - :track | 'admin_verify' | 'invite_team' - :series | 1 | 5 - end - - with_them do - it "raises an exception if option is not present" do - expect do - described_class.new(options: options.except(options_key), time_frame: 'all') - end.to raise_error(ArgumentError, %r{#{options_key} .* must be one of}) - end - - it "raises an exception if option has invalid value" do - expect do - options[options_key] = invalid_value - described_class.new(options: options, time_frame: 'all') - end.to raise_error(ArgumentError, %r{#{options_key} .* must be one of}) - end - - it "doesn't raise exceptions if option has valid value" do - options[options_key] = valid_value - described_class.new(options: options, time_frame: 'all') - end - end -end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/in_product_marketing_email_sent_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/in_product_marketing_email_sent_metric_spec.rb deleted file mode 100644 index 3c51368f396..00000000000 --- a/spec/lib/gitlab/usage/metrics/instrumentations/in_product_marketing_email_sent_metric_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Usage::Metrics::Instrumentations::InProductMarketingEmailSentMetric do - using RSpec::Parameterized::TableSyntax - - let(:email_attributes) { { track: 'verify', series: 0 } } - let(:expected_value) { 2 } - let(:expected_query) do - 'SELECT COUNT("in_product_marketing_emails"."id") FROM "in_product_marketing_emails" ' \ - 'WHERE "in_product_marketing_emails"."series" = 0 ' \ - 'AND "in_product_marketing_emails"."track" = 1' - end - - before do - create_list :in_product_marketing_email, 2, email_attributes - - create :in_product_marketing_email, email_attributes.merge(track: 'team') - create :in_product_marketing_email, email_attributes.merge(series: 1) - end - - it_behaves_like 'a correct instrumented metric value and query', { - options: { track: 'verify', series: 0 }, - time_frame: 'all' - } - - where(:options_key, :valid_value, :invalid_value) do - :track | 'admin_verify' | 'invite_team' - :series | 1 | 5 - end - - with_them do - it "raises an exception if option is not present" do - expect do - described_class.new(options: email_attributes.except(options_key), time_frame: 'all') - end.to raise_error(ArgumentError, %r{#{options_key} .* must be one of}) - end - - it "raises an exception if option has invalid value" do - expect do - email_attributes[options_key] = invalid_value - described_class.new(options: email_attributes, time_frame: 'all') - end.to raise_error(ArgumentError, %r{#{options_key} .* must be one of}) - end - - it "doesn't raise exceptions if option has valid value" do - email_attributes[options_key] = valid_value - described_class.new(options: email_attributes, time_frame: 'all') - end - end -end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/jira_imports_users_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/jira_imports_users_metric_spec.rb new file mode 100644 index 00000000000..86bc4d98372 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/jira_imports_users_metric_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::JiraImportsUsersMetric, feature_category: :importers do + let(:expected_value) { 3 } + let(:expected_query) { "SELECT COUNT(DISTINCT \"jira_imports\".\"user_id\") FROM \"jira_imports\"" } + + before_all do + import = create :jira_import_state, created_at: 3.days.ago + create :jira_import_state, created_at: 35.days.ago + create :jira_import_state, created_at: 3.days.ago + create :jira_import_state, created_at: 3.days.ago, user: import.user + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' } do + let(:expected_value) { 2 } + let(:start) { 30.days.ago.to_fs(:db) } + let(:finish) { 2.days.ago.to_fs(:db) } + let(:expected_query) do + "SELECT COUNT(DISTINCT \"jira_imports\".\"user_id\") FROM \"jira_imports\" " \ + "WHERE \"jira_imports\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'" + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/omniauth_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/omniauth_enabled_metric_spec.rb new file mode 100644 index 00000000000..20390e6abd9 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/omniauth_enabled_metric_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::OmniauthEnabledMetric, feature_category: :service_ping do + before do + allow(Gitlab::Auth).to receive(:omniauth_enabled?).and_return(expected_value) + end + + [true, false].each do |setting| + context "when the setting is #{setting}" do + let(:expected_value) { setting } + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'none' } + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/project_imports_creators_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/project_imports_creators_metric_spec.rb new file mode 100644 index 00000000000..2a0e0a1a591 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/project_imports_creators_metric_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::ProjectImportsCreatorsMetric, feature_category: :importers do + let(:expected_value) { 3 } + let(:expected_query) do + "SELECT COUNT(DISTINCT \"projects\".\"creator_id\") FROM \"projects\" " \ + "WHERE \"projects\".\"import_type\" IS NOT NULL" + end + + before_all do + project = create :project, import_type: :jira, created_at: 3.days.ago + create :project, import_type: :jira, created_at: 35.days.ago + create :project, import_type: :jira, created_at: 3.days.ago + create :project, created_at: 3.days.ago + create :project, import_type: :jira, created_at: 3.days.ago, creator: project.creator + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' } do + let(:expected_value) { 2 } + let(:start) { 30.days.ago.to_fs(:db) } + let(:finish) { 2.days.ago.to_fs(:db) } + let(:expected_query) do + "SELECT COUNT(DISTINCT \"projects\".\"creator_id\") FROM \"projects\" WHERE " \ + "\"projects\".\"import_type\" IS NOT NULL AND \"projects\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'" + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/prometheus_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/prometheus_enabled_metric_spec.rb new file mode 100644 index 00000000000..dbd44cc3309 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/prometheus_enabled_metric_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::PrometheusEnabledMetric, feature_category: :service_ping do + before do + allow(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(expected_value) + end + + [true, false].each do |setting| + context "when the setting is #{setting}" do + let(:expected_value) { setting } + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'none' } + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/prometheus_metrics_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/prometheus_metrics_enabled_metric_spec.rb new file mode 100644 index 00000000000..3e6812f3b34 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/prometheus_metrics_enabled_metric_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::PrometheusMetricsEnabledMetric, feature_category: :service_ping do + before do + allow(Gitlab::Metrics).to receive(:prometheus_metrics_enabled?).and_return(expected_value) + end + + [true, false].each do |setting| + context "when the setting is #{setting}" do + let(:expected_value) { setting } + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'none' } + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/reply_by_email_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/reply_by_email_enabled_metric_spec.rb new file mode 100644 index 00000000000..12eab4bb422 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/reply_by_email_enabled_metric_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::ReplyByEmailEnabledMetric, feature_category: :service_ping do + before do + allow(Gitlab::Email::IncomingEmail).to receive(:enabled?).and_return(expected_value) + end + + [true, false].each do |setting| + context "when the setting is #{setting}" do + let(:expected_value) { setting } + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'none' } + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb index f3aa1ba4f88..b357d6ea7e4 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb @@ -9,32 +9,112 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric, :clea end context 'with multiple similar events' do - let(:expected_value) { 10 } - before do + last_week = Date.today - 7.days + two_weeks_ago = last_week - 1.week + + redis_counter_key = described_class.redis_key('my_event', last_week) + 2.times do + Gitlab::Redis::SharedState.with { |redis| redis.incr(redis_counter_key) } + end + + redis_counter_key = described_class.redis_key('my_event', two_weeks_ago) + 3.times do + Gitlab::Redis::SharedState.with { |redis| redis.incr(redis_counter_key) } + end + 10.times do Gitlab::InternalEvents.track_event('my_event') end end - it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', events: [{ name: 'my_event' }] } + context "with an 'all' time_frame" do + let(:expected_value) { 10 } + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', events: [{ name: 'my_event' }] } + end + + context "with a 7d time_frame" do + let(:expected_value) { 2 } + + it_behaves_like 'a correct instrumented metric value', { time_frame: '7d', events: [{ name: 'my_event' }] } + end + + context "with a 28d time_frame" do + let(:expected_value) { 5 } + + it_behaves_like 'a correct instrumented metric value', { time_frame: '28d', events: [{ name: 'my_event' }] } + end end context 'with multiple different events' do let(:expected_value) { 2 } before do + last_week = Date.today - 7.days + two_weeks_ago = last_week - 1.week + + 2.times do + redis_counter_key = + Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key('my_event1', last_week) + Gitlab::Redis::SharedState.with { |redis| redis.incr(redis_counter_key) } + end + + 3.times do + redis_counter_key = + Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key('my_event1', two_weeks_ago) + Gitlab::Redis::SharedState.with { |redis| redis.incr(redis_counter_key) } + end + + 4.times do + redis_counter_key = + Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key('my_event2', last_week) + Gitlab::Redis::SharedState.with { |redis| redis.incr(redis_counter_key) } + end + Gitlab::InternalEvents.track_event('my_event1') Gitlab::InternalEvents.track_event('my_event2') end - it_behaves_like 'a correct instrumented metric value', - { time_frame: 'all', events: [{ name: 'my_event1' }, { name: 'my_event2' }] } + context "with an 'all' time_frame" do + let(:expected_value) { 2 } + + it_behaves_like 'a correct instrumented metric value', + { time_frame: 'all', events: [{ name: 'my_event1' }, { name: 'my_event2' }] } + end + + context "with a 7d time_frame" do + let(:expected_value) { 6 } + + it_behaves_like 'a correct instrumented metric value', + { time_frame: '7d', events: [{ name: 'my_event1' }, { name: 'my_event2' }] } + end + + context "with a 28d time_frame" do + let(:expected_value) { 9 } + + it_behaves_like 'a correct instrumented metric value', + { time_frame: '28d', events: [{ name: 'my_event1' }, { name: 'my_event2' }] } + end + end + + context "with an invalid time_frame" do + let(:metric) { described_class.new(time_frame: '14d', events: [{ name: 'my_event' }]) } + + it 'raises an exception' do + expect { metric.value }.to raise_error(/Unknown time frame/) + end end describe '.redis_key' do it 'adds the key prefix to the event name' do expect(described_class.redis_key('my_event')).to eq('{event_counters}_my_event') end + + context "with a date" do + it 'adds the key prefix and suffix to the event name' do + expect(described_class.redis_key('my_event', Date.new(2023, 10, 19))).to eq("{event_counters}_my_event-2023-42") + end + end end end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/unique_users_all_imports_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/unique_users_all_imports_metric_spec.rb new file mode 100644 index 00000000000..4fdabb86e23 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/unique_users_all_imports_metric_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::UniqueUsersAllImportsMetric, feature_category: :importers do + let(:expected_value) { 6 } + let(:expected_query) do + <<~SQL.squish + SELECT + (SELECT COUNT(DISTINCT "projects"."creator_id") FROM "projects" WHERE "projects"."import_type" IS NOT NULL) + + (SELECT COUNT(DISTINCT "bulk_imports"."user_id") FROM "bulk_imports") + + (SELECT COUNT(DISTINCT "jira_imports"."user_id") FROM "jira_imports") + + (SELECT COUNT(DISTINCT "csv_issue_imports"."user_id") FROM "csv_issue_imports") + + (SELECT COUNT(DISTINCT "group_import_states"."user_id") FROM "group_import_states") + SQL + end + + before_all do + import = create :jira_import_state, created_at: 3.days.ago + create :jira_import_state, created_at: 35.days.ago + create :jira_import_state, created_at: 3.days.ago, user: import.user + + create :group_import_state, created_at: 3.days.ago + create :issue_csv_import, created_at: 3.days.ago + create :bulk_import, created_at: 3.days.ago + create :project, import_type: :jira, created_at: 3.days.ago + end + + before do + described_class::IMPORTS_METRICS.each do |submetric_class| + metric = submetric_class.new(time_frame: time_frame, options: options) + allow(metric.send(:relation).connection).to receive(:transaction_open?).and_return(false) + end + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' } do + let(:expected_value) { 5 } + let(:start) { 30.days.ago.to_fs(:db) } + let(:finish) { 2.days.ago.to_fs(:db) } + let(:expected_query) do + <<~SQL.squish + SELECT + (SELECT COUNT(DISTINCT "projects"."creator_id") FROM "projects" WHERE "projects"."import_type" IS NOT NULL AND "projects"."created_at" BETWEEN '#{start}' AND '#{finish}') + + (SELECT COUNT(DISTINCT "bulk_imports"."user_id") FROM "bulk_imports" WHERE "bulk_imports"."created_at" BETWEEN '#{start}' AND '#{finish}') + + (SELECT COUNT(DISTINCT "jira_imports"."user_id") FROM "jira_imports" WHERE "jira_imports"."created_at" BETWEEN '#{start}' AND '#{finish}') + + (SELECT COUNT(DISTINCT "csv_issue_imports"."user_id") FROM "csv_issue_imports" WHERE "csv_issue_imports"."created_at" BETWEEN '#{start}' AND '#{finish}') + + (SELECT COUNT(DISTINCT "group_import_states"."user_id") FROM "group_import_states" WHERE "group_import_states"."created_at" BETWEEN '#{start}' AND '#{finish}') + SQL + end + end +end |