Commit fc5c4c4e authored by Mikołaj Wawrzyniak's avatar Mikołaj Wawrzyniak

Merge branch '338029-merge-instrumentation-classes-data-to-service-ping-data' into 'master'

Merge instrumentation classes data to service ping data

See merge request gitlab-org/gitlab!68808
parents 10d7ca38 2d4a09ef
---
name: usage_data_instrumentation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68808
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338029
milestone: '14.5'
type: development
group: group::product intelligence
default_enabled: false
...@@ -86,10 +86,37 @@ RSpec.describe 'Every metric definition' do ...@@ -86,10 +86,37 @@ RSpec.describe 'Every metric definition' do
stub_usage_data_connections stub_usage_data_connections
end end
it 'is included in the Usage Ping hash structure', :aggregate_failures do context 'with usage_data_instrumentation feature flag' do
msg = "see https://docs.gitlab.com/ee/development/service_ping/metrics_dictionary.html#metrics-added-dynamic-to-service-ping-payload" let(:msg) { 'see https://docs.gitlab.com/ee/development/service_ping/metrics_dictionary.html#metrics-added-dynamic-to-service-ping-payload' }
expect(metric_files_key_paths).to match_array(usage_ping_key_paths)
expect(metric_files_key_paths).to match_array(usage_ping_key_paths), msg context 'when enabled' do
let(:instrumentation_class_keys) do
Gitlab::Usage::MetricDefinition.with_instrumentation_class.map(&:key)
.reject { |v| v =~ Regexp.union(ignored_usage_ping_key_patterns) }
end
let(:files_key_paths) do
(metric_files_key_paths + instrumentation_class_keys).to_set
end
before do
stub_feature_flags(usage_data_instrumentation: true)
end
it 'is included in the Usage Ping hash structure', :aggregate_failures do
expect(files_key_paths).to eql(usage_ping_key_paths.to_set), msg
end
end
context 'when disabled' do
before do
stub_feature_flags(usage_data_instrumentation: false)
end
it 'is included in the Usage Ping hash structure', :aggregate_failures do
expect(metric_files_key_paths).to match_array(usage_ping_key_paths), msg
end
end
end end
context 'with value json schema' do context 'with value json schema' do
......
...@@ -10,7 +10,7 @@ RSpec.describe Gitlab::UsageDataNonSqlMetrics do ...@@ -10,7 +10,7 @@ RSpec.describe Gitlab::UsageDataNonSqlMetrics do
end end
describe '.uncached_data' do describe '.uncached_data' do
it 'does not make DB calls' do it 'does make instrumentations_class DB calls' do
recorder = ActiveRecord::QueryRecorder.new do recorder = ActiveRecord::QueryRecorder.new do
described_class.uncached_data described_class.uncached_data
end end
......
...@@ -62,7 +62,7 @@ RSpec.describe Gitlab::UsageData do ...@@ -62,7 +62,7 @@ RSpec.describe Gitlab::UsageData do
subject { described_class.data } subject { described_class.data }
it 'gathers usage data' do it 'gathers usage data' do
expect(subject.keys).to include(*%i( expect(subject.keys).to include(*%w(
historical_max_users historical_max_users
license_add_ons license_add_ons
license_plan license_plan
...@@ -85,7 +85,7 @@ RSpec.describe Gitlab::UsageData do ...@@ -85,7 +85,7 @@ RSpec.describe Gitlab::UsageData do
expect(count_data[:boards]).to eq(1) expect(count_data[:boards]).to eq(1)
expect(count_data[:projects]).to eq(3) expect(count_data[:projects]).to eq(3)
expect(count_data.keys).to include(*%i( expect(count_data.keys).to include(*%w(
confidential_epics confidential_epics
container_scanning_jobs container_scanning_jobs
coverage_fuzzing_jobs coverage_fuzzing_jobs
...@@ -200,10 +200,7 @@ RSpec.describe Gitlab::UsageData do ...@@ -200,10 +200,7 @@ RSpec.describe Gitlab::UsageData do
it 'gathers license data' do it 'gathers license data' do
license = ::License.current license = ::License.current
expect(subject[:license_md5]).to eq(Digest::MD5.hexdigest(license.data))
expect(subject[:license_id]).to eq(license.license_id) expect(subject[:license_id]).to eq(license.license_id)
expect(subject[:historical_max_users]).to eq(license.historical_max)
expect(subject[:licensee]).to eq(license.licensee)
expect(subject[:license_user_count]).to eq(license.restricted_user_count) expect(subject[:license_user_count]).to eq(license.restricted_user_count)
expect(subject[:license_starts_at]).to eq(license.starts_at) expect(subject[:license_starts_at]).to eq(license.starts_at)
expect(subject[:license_expires_at]).to eq(license.expires_at) expect(subject[:license_expires_at]).to eq(license.expires_at)
...@@ -212,6 +209,39 @@ RSpec.describe Gitlab::UsageData do ...@@ -212,6 +209,39 @@ RSpec.describe Gitlab::UsageData do
expect(subject[:license_subscription_id]).to eq(license.subscription_id) expect(subject[:license_subscription_id]).to eq(license.subscription_id)
expect(subject[:license_billable_users]).to eq(license.daily_billable_users_count) expect(subject[:license_billable_users]).to eq(license.daily_billable_users_count)
end end
context 'with usage_data_instrumentation feature flag' do
let(:license) { ::License.current }
context 'when enabled' do
before do
stub_feature_flags(usage_data_instrumentation: true)
end
it 'returns fallback value to be overriden' do
expect(subject[:licensee]).to eq(Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(subject[:license_md5]).to eq(Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(subject[:historical_max_users]).to eq(Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
uncached_data = described_class.uncached_data
expect(uncached_data[:licensee]).to eq(license.licensee)
expect(uncached_data[:license_md5]).to eq(Digest::MD5.hexdigest(license.data))
expect(uncached_data[:historical_max_users]).to eq(license.historical_max)
end
end
context 'when disabled' do
before do
stub_feature_flags(usage_data_instrumentation: false)
end
it 'computes historical_max_users, licensee and license_md5 values' do
expect(subject[:licensee]).to eq(license.licensee)
expect(subject[:license_md5]).to eq(Digest::MD5.hexdigest(license.data))
expect(subject[:historical_max_users]).to eq(license.historical_max)
end
end
end
end end
describe '.requirements_counts' do describe '.requirements_counts' do
...@@ -541,7 +571,7 @@ RSpec.describe Gitlab::UsageData do ...@@ -541,7 +571,7 @@ RSpec.describe Gitlab::UsageData do
end end
describe 'usage_activity_by_stage_release' do describe 'usage_activity_by_stage_release' do
it 'includes accurate usage_activity_by_stage data' do before do
stub_licensed_features(group_milestone_project_releases: true) stub_licensed_features(group_milestone_project_releases: true)
group_milestone = create(:milestone, :on_group) group_milestone = create(:milestone, :on_group)
project = create(:project, group: group_milestone.group) project = create(:project, group: group_milestone.group)
...@@ -551,15 +581,41 @@ RSpec.describe Gitlab::UsageData do ...@@ -551,15 +581,41 @@ RSpec.describe Gitlab::UsageData do
create(:release, created_at: 3.days.ago, project: project, milestones: [group_milestone]) create(:release, created_at: 3.days.ago, project: project, milestones: [group_milestone])
end end
end
expect(described_class.usage_activity_by_stage_release({})).to include( it 'includes accurate usage_activity_by_stage data' do
projects_mirrored_with_pipelines_enabled: 2, expect(described_class.usage_activity_by_stage_release({})).to include(projects_mirrored_with_pipelines_enabled: 2)
releases_with_group_milestones: 2 expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(projects_mirrored_with_pipelines_enabled: 1)
) end
expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(
projects_mirrored_with_pipelines_enabled: 1, context 'with usage_data_instrumentation feature flag' do
releases_with_group_milestones: 1 let(:license) { ::License.current }
)
context 'when enabled' do
before do
stub_feature_flags(usage_data_instrumentation: true)
end
it 'returns fallback value to be overriden' do
expect(described_class.usage_activity_by_stage_release({})).to include(releases_with_group_milestones: Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(releases_with_group_milestones: Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
uncached_data = described_class.uncached_data
expect(uncached_data[:usage_activity_by_stage][:release]).to include(releases_with_milestones: 2)
expect(uncached_data[:usage_activity_by_stage_monthly][:release]).to include(releases_with_milestones: 1)
end
end
context 'when disabled' do
before do
stub_feature_flags(usage_data_instrumentation: false)
end
it 'computes releases_with_group_milestones values' do
expect(described_class.usage_activity_by_stage_release({})).to include(releases_with_group_milestones: 2)
expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(releases_with_group_milestones: 1)
end
end
end end
end end
......
...@@ -25,6 +25,10 @@ module Gitlab ...@@ -25,6 +25,10 @@ module Gitlab
unflatten_key_path(intrumentation_object.instrumentation) unflatten_key_path(intrumentation_object.instrumentation)
end end
def with_suggested_name
unflatten_key_path(intrumentation_object.suggested_name)
end
private private
def unflatten_key_path(value) def unflatten_key_path(value)
......
...@@ -18,6 +18,10 @@ module Gitlab ...@@ -18,6 +18,10 @@ module Gitlab
private private
def instrumentation_metrics
::Gitlab::UsageDataMetrics.suggested_names
end
def count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil) def count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
Gitlab::Usage::Metrics::NameSuggestion.for(:count, column: column, relation: relation) Gitlab::Usage::Metrics::NameSuggestion.for(:count, column: column, relation: relation)
end end
......
...@@ -45,23 +45,10 @@ module Gitlab ...@@ -45,23 +45,10 @@ module Gitlab
clear_memoized clear_memoized
with_finished_at(:recording_ce_finished_at) do with_finished_at(:recording_ce_finished_at) do
license_usage_data usage_data = usage_data_metrics
.merge(system_usage_data_license) usage_data = usage_data.with_indifferent_access.deep_merge(instrumentation_metrics.with_indifferent_access) if Feature.enabled?(:usage_data_instrumentation)
.merge(system_usage_data_settings)
.merge(system_usage_data) usage_data
.merge(system_usage_data_monthly)
.merge(system_usage_data_weekly)
.merge(features_usage_data)
.merge(components_usage_data)
.merge(object_store_usage_data)
.merge(topology_usage_data)
.merge(usage_activity_by_stage)
.merge(usage_activity_by_stage(:usage_activity_by_stage_monthly, monthly_time_range_db_params))
.merge(analytics_unique_visits_data)
.merge(compliance_unique_visits_data)
.merge(search_unique_visits_data)
.merge(redis_hll_counters)
.deep_merge(aggregated_metrics_data)
end end
end end
...@@ -729,6 +716,30 @@ module Gitlab ...@@ -729,6 +716,30 @@ module Gitlab
private private
def usage_data_metrics
license_usage_data
.merge(system_usage_data_license)
.merge(system_usage_data_settings)
.merge(system_usage_data)
.merge(system_usage_data_monthly)
.merge(system_usage_data_weekly)
.merge(features_usage_data)
.merge(components_usage_data)
.merge(object_store_usage_data)
.merge(topology_usage_data)
.merge(usage_activity_by_stage)
.merge(usage_activity_by_stage(:usage_activity_by_stage_monthly, monthly_time_range_db_params))
.merge(analytics_unique_visits_data)
.merge(compliance_unique_visits_data)
.merge(search_unique_visits_data)
.merge(redis_hll_counters)
.deep_merge(aggregated_metrics_data)
end
def instrumentation_metrics
Gitlab::UsageDataMetrics.uncached_data # rubocop:disable UsageData/LargeTable
end
def metric_time_period(time_period) def metric_time_period(time_period)
time_period.present? ? '28d' : 'none' time_period.present? ? '28d' : 'none'
end end
......
...@@ -5,7 +5,17 @@ module Gitlab ...@@ -5,7 +5,17 @@ module Gitlab
class << self class << self
# Build the Usage Ping JSON payload from metrics YAML definitions which have instrumentation class set # Build the Usage Ping JSON payload from metrics YAML definitions which have instrumentation class set
def uncached_data def uncached_data
::Gitlab::Usage::Metric.all.map(&:with_value).reduce({}, :deep_merge) build_payload(:with_value)
end
def suggested_names
build_payload(:with_suggested_name)
end
private
def build_payload(method_symbol)
::Gitlab::Usage::Metric.all.map(&method_symbol).reduce({}, :deep_merge)
end end
end end
end end
......
...@@ -6,7 +6,10 @@ module Gitlab ...@@ -6,7 +6,10 @@ module Gitlab
class << self class << self
def uncached_data def uncached_data
super.with_indifferent_access.deep_merge(instrumentation_metrics_queries.with_indifferent_access) # instrumentation_metrics is already included with feature flag enabled
return super if Feature.enabled?(:usage_data_instrumentation)
super.with_indifferent_access.deep_merge(instrumentation_metrics.with_indifferent_access)
end end
def add_metric(metric, time_frame: 'none') def add_metric(metric, time_frame: 'none')
...@@ -50,7 +53,7 @@ module Gitlab ...@@ -50,7 +53,7 @@ module Gitlab
private private
def instrumentation_metrics_queries def instrumentation_metrics
::Gitlab::Usage::Metric.all.map(&:with_instrumentation).reduce({}, :deep_merge) ::Gitlab::Usage::Metric.all.map(&:with_instrumentation).reduce({}, :deep_merge)
end end
end end
......
...@@ -6,7 +6,10 @@ module Gitlab ...@@ -6,7 +6,10 @@ module Gitlab
class UsageDataQueries < UsageData class UsageDataQueries < UsageData
class << self class << self
def uncached_data def uncached_data
super.with_indifferent_access.deep_merge(instrumentation_metrics_queries.with_indifferent_access) # instrumentation_metrics is already included with feature flag enabled
return super if Feature.enabled?(:usage_data_instrumentation)
super.with_indifferent_access.deep_merge(instrumentation_metrics.with_indifferent_access)
end end
def add_metric(metric, time_frame: 'none') def add_metric(metric, time_frame: 'none')
...@@ -71,7 +74,7 @@ module Gitlab ...@@ -71,7 +74,7 @@ module Gitlab
private private
def instrumentation_metrics_queries def instrumentation_metrics
::Gitlab::Usage::Metric.all.map(&:with_instrumentation).reduce({}, :deep_merge) ::Gitlab::Usage::Metric.all.map(&:with_instrumentation).reduce({}, :deep_merge)
end end
end end
......
...@@ -43,8 +43,13 @@ module Gitlab ...@@ -43,8 +43,13 @@ module Gitlab
HISTOGRAM_FALLBACK = { '-1' => -1 }.freeze HISTOGRAM_FALLBACK = { '-1' => -1 }.freeze
DISTRIBUTED_HLL_FALLBACK = -2 DISTRIBUTED_HLL_FALLBACK = -2
MAX_BUCKET_SIZE = 100 MAX_BUCKET_SIZE = 100
INSTRUMENTATION_CLASS_FALLBACK = -100
def add_metric(metric, time_frame: 'none') def add_metric(metric, time_frame: 'none')
# Results of this method should be overwritten by instrumentation class values
# -100 indicates the metric was not properly merged.
return INSTRUMENTATION_CLASS_FALLBACK if Feature.enabled?(:usage_data_instrumentation)
metric_class = "Gitlab::Usage::Metrics::Instrumentations::#{metric}".constantize metric_class = "Gitlab::Usage::Metrics::Instrumentations::#{metric}".constantize
metric_class.new(time_frame: time_frame).value metric_class.new(time_frame: time_frame).value
......
...@@ -45,4 +45,10 @@ RSpec.describe Gitlab::Usage::Metric do ...@@ -45,4 +45,10 @@ RSpec.describe Gitlab::Usage::Metric do
expect(described_class.new(issue_count_metric_definiton).with_instrumentation).to eq({ counts: { issues: "SELECT COUNT(\"issues\".\"id\") FROM \"issues\"" } }) expect(described_class.new(issue_count_metric_definiton).with_instrumentation).to eq({ counts: { issues: "SELECT COUNT(\"issues\".\"id\") FROM \"issues\"" } })
end end
end end
describe '#with_suggested_name' do
it 'returns key_path metric with the corresponding generated query' do
expect(described_class.new(issue_count_metric_definiton).with_suggested_name).to eq({ counts: { issues: 'count_issues' } })
end
end
end end
...@@ -25,10 +25,30 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do ...@@ -25,10 +25,30 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do
end end
context 'for count with default column metrics' do context 'for count with default column metrics' do
it_behaves_like 'name suggestion' do context 'with usage_data_instrumentation feature flag' do
# corresponding metric is collected with count(Board) context 'when enabled' do
let(:key_path) { 'counts.boards' } before do
let(:name_suggestion) { /count_boards/ } stub_feature_flags(usage_data_instrumentation: true)
end
it_behaves_like 'name suggestion' do
# corresponding metric is collected with ::Gitlab::UsageDataMetrics.suggested_names
let(:key_path) { 'counts.boards' }
let(:name_suggestion) { /count_boards/ }
end
end
context 'when disabled' do
before do
stub_feature_flags(usage_data_instrumentation: false)
end
it_behaves_like 'name suggestion' do
# corresponding metric is collected with count(Board)
let(:key_path) { 'counts.boards' }
let(:name_suggestion) { /count_boards/ }
end
end
end end
end end
......
...@@ -76,4 +76,16 @@ RSpec.describe Gitlab::UsageDataMetrics do ...@@ -76,4 +76,16 @@ RSpec.describe Gitlab::UsageDataMetrics do
end end
end end
end end
describe '.suggested_names' do
subject { described_class.suggested_names }
let(:suggested_names) do
::Gitlab::Usage::Metric.all.map(&:with_suggested_name).reduce({}, :deep_merge)
end
it 'includes Service Ping suggested names' do
expect(subject).to match_array(suggested_names)
end
end
end end
...@@ -80,6 +80,12 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -80,6 +80,12 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
end end
end end
end end
it 'allows indifferent access' do
allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).and_return(1)
expect(subject[:search_unique_visits][:search_unique_visits_for_any_target_monthly]).to eq(1)
expect(subject[:search_unique_visits]['search_unique_visits_for_any_target_monthly']).to eq(1)
end
end end
describe 'usage_activity_by_stage_package' do describe 'usage_activity_by_stage_package' do
...@@ -428,7 +434,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -428,7 +434,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
end end
expect(described_class.usage_activity_by_stage_plan({})).to include( expect(described_class.usage_activity_by_stage_plan({})).to include(
issues: 3,
notes: 2, notes: 2,
projects: 2, projects: 2,
todos: 2, todos: 2,
...@@ -439,7 +444,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -439,7 +444,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
projects_jira_dvcs_server_active: 2 projects_jira_dvcs_server_active: 2
) )
expect(described_class.usage_activity_by_stage_plan(described_class.monthly_time_range_db_params)).to include( expect(described_class.usage_activity_by_stage_plan(described_class.monthly_time_range_db_params)).to include(
issues: 2,
notes: 1, notes: 1,
projects: 1, projects: 1,
todos: 1, todos: 1,
...@@ -450,6 +454,44 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -450,6 +454,44 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
projects_jira_dvcs_server_active: 1 projects_jira_dvcs_server_active: 1
) )
end end
context 'with usage_data_instrumentation feature flag' do
context 'when enabled' do
it 'merges the data from instrumentation classes' do
stub_feature_flags(usage_data_instrumentation: true)
for_defined_days_back do
user = create(:user)
project = create(:project, creator: user)
create(:issue, project: project, author: user)
create(:issue, project: project, author: User.support_bot)
end
expect(described_class.usage_activity_by_stage_plan({})).to include(issues: Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(described_class.usage_activity_by_stage_plan(described_class.monthly_time_range_db_params)).to include(issues: Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
uncached_data = described_class.uncached_data
expect(uncached_data[:usage_activity_by_stage][:plan]).to include(issues: 3)
expect(uncached_data[:usage_activity_by_stage_monthly][:plan]).to include(issues: 2)
end
end
context 'when disabled' do
it 'does not merge the data from instrumentation classes' do
stub_feature_flags(usage_data_instrumentation: false)
for_defined_days_back do
user = create(:user)
project = create(:project, creator: user)
create(:issue, project: project, author: user)
create(:issue, project: project, author: User.support_bot)
end
expect(described_class.usage_activity_by_stage_plan({})).to include(issues: 3)
expect(described_class.usage_activity_by_stage_plan(described_class.monthly_time_range_db_params)).to include(issues: 2)
end
end
end
end end
describe 'usage_activity_by_stage_release' do describe 'usage_activity_by_stage_release' do
...@@ -466,17 +508,53 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -466,17 +508,53 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
deployments: 2, deployments: 2,
failed_deployments: 2, failed_deployments: 2,
releases: 2, releases: 2,
successful_deployments: 2, successful_deployments: 2
releases_with_milestones: 2
) )
expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include( expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(
deployments: 1, deployments: 1,
failed_deployments: 1, failed_deployments: 1,
releases: 1, releases: 1,
successful_deployments: 1, successful_deployments: 1
releases_with_milestones: 1
) )
end end
context 'with usage_data_instrumentation feature flag' do
before do
for_defined_days_back do
user = create(:user)
create(:deployment, :failed, user: user)
release = create(:release, author: user)
create(:milestone, project: release.project, releases: [release])
create(:deployment, :success, user: user)
end
end
context 'when enabled' do
before do
stub_feature_flags(usage_data_instrumentation: true)
end
it 'merges data from instrumentation classes' do
expect(described_class.usage_activity_by_stage_release({})).to include(releases_with_milestones: Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(releases_with_milestones: Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
uncached_data = described_class.uncached_data
expect(uncached_data[:usage_activity_by_stage][:release]).to include(releases_with_milestones: 2)
expect(uncached_data[:usage_activity_by_stage_monthly][:release]).to include(releases_with_milestones: 1)
end
end
context 'when disabled' do
before do
stub_feature_flags(usage_data_instrumentation: false)
end
it 'does not merge data from instrumentation classes' do
expect(described_class.usage_activity_by_stage_release({})).to include(releases_with_milestones: 2)
expect(described_class.usage_activity_by_stage_release(described_class.monthly_time_range_db_params)).to include(releases_with_milestones: 1)
end
end
end
end end
describe 'usage_activity_by_stage_verify' do describe 'usage_activity_by_stage_verify' do
...@@ -525,16 +603,16 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -525,16 +603,16 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
subject { described_class.data } subject { described_class.data }
it 'gathers usage data' do it 'gathers usage data' do
expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS) expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS.map(&:to_s))
end end
it 'gathers usage counts', :aggregate_failures do it 'gathers usage counts', :aggregate_failures do
count_data = subject[:counts] count_data = subject[:counts]
expect(count_data[:boards]).to eq(1) expect(count_data[:boards]).to eq(1)
expect(count_data[:projects]).to eq(4) expect(count_data[:projects]).to eq(4)
expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS) count_keys = UsageDataHelpers::COUNTS_KEYS.map(&:to_s)
expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty expect(count_data.keys).to include(*count_keys)
expect(count_keys - count_data.keys).to be_empty
expect(count_data.values).to all(be_a_kind_of(Integer)) expect(count_data.values).to all(be_a_kind_of(Integer))
end end
...@@ -619,7 +697,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -619,7 +697,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
external_diffs: { enabled: false }, external_diffs: { enabled: false },
lfs: { enabled: true, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } }, lfs: { enabled: true, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
uploads: { enabled: nil, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } }, uploads: { enabled: nil, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } } packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } }.with_indifferent_access
) )
end end
...@@ -793,12 +871,37 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -793,12 +871,37 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
subject { described_class.license_usage_data } subject { described_class.license_usage_data }
it 'gathers license data' do it 'gathers license data' do
expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
expect(subject[:version]).to eq(Gitlab::VERSION) expect(subject[:version]).to eq(Gitlab::VERSION)
expect(subject[:installation_type]).to eq('gitlab-development-kit') expect(subject[:installation_type]).to eq('gitlab-development-kit')
expect(subject[:active_user_count]).to eq(User.active.size)
expect(subject[:recorded_at]).to be_a(Time) expect(subject[:recorded_at]).to be_a(Time)
end end
context 'with usage_data_instrumentation feature flag' do
context 'when enabled' do
it 'merges uuid and hostname data from instrumentation classes' do
stub_feature_flags(usage_data_instrumentation: true)
expect(subject[:uuid]).to eq(Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(subject[:hostname]).to eq(Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
expect(subject[:active_user_count]).to eq(Gitlab::Utils::UsageData::INSTRUMENTATION_CLASS_FALLBACK)
uncached_data = described_class.data
expect(uncached_data[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
expect(uncached_data[:hostname]).to eq(Gitlab.config.gitlab.host)
expect(uncached_data[:active_user_count]).to eq(User.active.size)
end
end
context 'when disabled' do
it 'does not merge uuid and hostname data from instrumentation classes' do
stub_feature_flags(usage_data_instrumentation: false)
expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
expect(subject[:hostname]).to eq(Gitlab.config.gitlab.host)
expect(subject[:active_user_count]).to eq(User.active.size)
end
end
end
end end
context 'when not relying on database records' do context 'when not relying on database records' do
...@@ -1061,18 +1164,46 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -1061,18 +1164,46 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:settings][:gitaly_apdex]).to be_within(0.001).of(0.95) expect(subject[:settings][:gitaly_apdex]).to be_within(0.001).of(0.95)
end end
it 'reports collected data categories' do context 'with usage_data_instrumentation feature flag' do
expected_value = %w[standard subscription operational optional] context 'when enabled' do
before do
stub_feature_flags(usage_data_instrumentation: true)
end
it 'reports collected data categories' do
expected_value = %w[standard subscription operational optional]
allow_next_instance_of(ServicePing::PermitDataCategoriesService) do |instance|
expect(instance).to receive(:execute).and_return(expected_value)
end
expect(described_class.data[:settings][:collected_data_categories]).to eq(expected_value)
end
allow_next_instance_of(ServicePing::PermitDataCategoriesService) do |instance| it 'gathers service_ping_features_enabled' do
expect(instance).to receive(:execute).and_return(expected_value) expect(described_class.data[:settings][:service_ping_features_enabled]).to eq(Gitlab::CurrentSettings.usage_ping_features_enabled)
end
end end
expect(subject[:settings][:collected_data_categories]).to eq(expected_value) context 'when disabled' do
end before do
stub_feature_flags(usage_data_instrumentation: false)
end
it 'reports collected data categories' do
expected_value = %w[standard subscription operational optional]
it 'gathers service_ping_features_enabled' do allow_next_instance_of(ServicePing::PermitDataCategoriesService) do |instance|
expect(subject[:settings][:service_ping_features_enabled]).to eq(Gitlab::CurrentSettings.usage_ping_features_enabled) expect(instance).to receive(:execute).and_return(expected_value)
end
expect(subject[:settings][:collected_data_categories]).to eq(expected_value)
end
it 'gathers service_ping_features_enabled' do
expect(subject[:settings][:service_ping_features_enabled]).to eq(Gitlab::CurrentSettings.usage_ping_features_enabled)
end
end
end end
it 'gathers user_cap_feature_enabled' do it 'gathers user_cap_feature_enabled' do
......
...@@ -8,8 +8,26 @@ RSpec.describe Gitlab::Utils::UsageData do ...@@ -8,8 +8,26 @@ RSpec.describe Gitlab::Utils::UsageData do
describe '#add_metric' do describe '#add_metric' do
let(:metric) { 'UuidMetric'} let(:metric) { 'UuidMetric'}
it 'computes the metric value for given metric' do context 'with usage_data_instrumentation feature flag' do
expect(described_class.add_metric(metric)).to eq(Gitlab::CurrentSettings.uuid) context 'when enabled' do
before do
stub_feature_flags(usage_data_instrumentation: true)
end
it 'returns -100 value to be overriden' do
expect(described_class.add_metric(metric)).to eq(-100)
end
end
context 'when disabled' do
before do
stub_feature_flags(usage_data_instrumentation: false)
end
it 'computes the metric value for given metric' do
expect(described_class.add_metric(metric)).to eq(Gitlab::CurrentSettings.uuid)
end
end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment