diff options
Diffstat (limited to 'spec/lib/gitlab/usage_data_spec.rb')
-rw-r--r-- | spec/lib/gitlab/usage_data_spec.rb | 277 |
1 files changed, 236 insertions, 41 deletions
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 3be8a770b2b..6631a0d3cc6 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -12,19 +12,20 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do describe '.uncached_data' do describe '.usage_activity_by_stage' do - it 'includes usage_activity_by_stage data' do - uncached_data = described_class.uncached_data + subject { described_class.uncached_data } - expect(uncached_data).to include(:usage_activity_by_stage) - expect(uncached_data).to include(:usage_activity_by_stage_monthly) - expect(uncached_data[:usage_activity_by_stage]) + it 'includes usage_activity_by_stage data' do + is_expected.to include(:usage_activity_by_stage) + is_expected.to include(:usage_activity_by_stage_monthly) + expect(subject[:usage_activity_by_stage]) .to include(:configure, :create, :manage, :monitor, :plan, :release, :verify) - expect(uncached_data[:usage_activity_by_stage_monthly]) + expect(subject[:usage_activity_by_stage_monthly]) .to include(:configure, :create, :manage, :monitor, :plan, :release, :verify) end it 'clears memoized values' do values = %i(issue_minimum_id issue_maximum_id + project_minimum_id project_maximum_id user_minimum_id user_maximum_id unique_visit_service deployment_minimum_id deployment_maximum_id approval_merge_request_rule_minimum_id @@ -33,15 +34,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(described_class).to receive(:clear_memoization).with(key) end - described_class.uncached_data + subject end it 'merge_requests_users is included only in montly counters' do - uncached_data = described_class.uncached_data - - expect(uncached_data[:usage_activity_by_stage][:create]) + expect(subject[:usage_activity_by_stage][:create]) .not_to include(:merge_requests_users) - expect(uncached_data[:usage_activity_by_stage_monthly][:create]) + expect(subject[:usage_activity_by_stage_monthly][:create]) .to include(:merge_requests_users) end end @@ -56,6 +55,21 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do end end + describe 'usage_activity_by_stage_package' do + it 'includes accurate usage_activity_by_stage data' do + for_defined_days_back do + create(:project, packages: [create(:package)] ) + end + + expect(described_class.usage_activity_by_stage_package({})).to eq( + projects_with_packages: 2 + ) + expect(described_class.usage_activity_by_stage_package(described_class.last_28_days_time_period)).to eq( + projects_with_packages: 1 + ) + end + end + describe '.usage_activity_by_stage_configure' do it 'includes accurate usage_activity_by_stage data' do for_defined_days_back do @@ -178,6 +192,58 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ) end + it 'includes imports usage data' do + for_defined_days_back do + user = create(:user) + + %w(gitlab_project gitlab github bitbucket bitbucket_server gitea git manifest fogbugz phabricator).each do |type| + create(:project, import_type: type, creator_id: user.id) + end + + jira_project = create(:project, creator_id: user.id) + create(:jira_import_state, :finished, project: jira_project) + end + + expect(described_class.usage_activity_by_stage_manage({})).to include( + { + projects_imported: { + gitlab_project: 2, + gitlab: 2, + github: 2, + bitbucket: 2, + bitbucket_server: 2, + gitea: 2, + git: 2, + manifest: 2 + }, + issues_imported: { + jira: 2, + fogbugz: 2, + phabricator: 2 + } + } + ) + expect(described_class.usage_activity_by_stage_manage(described_class.last_28_days_time_period)).to include( + { + projects_imported: { + gitlab_project: 1, + gitlab: 1, + github: 1, + bitbucket: 1, + bitbucket_server: 1, + gitea: 1, + git: 1, + manifest: 1 + }, + issues_imported: { + jira: 1, + fogbugz: 1, + phabricator: 1 + } + } + ) + end + def omniauth_providers [ OpenStruct.new(name: 'google_oauth2'), @@ -218,6 +284,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do create(:issue, project: project, author: User.support_bot) create(:note, project: project, noteable: issue, author: user) create(:todo, project: project, target: issue, author: user) + create(:jira_service, :jira_cloud_service, active: true, project: create(:project, :jira_dvcs_cloud, creator: user)) + create(:jira_service, active: true, project: create(:project, :jira_dvcs_server, creator: user)) end expect(described_class.usage_activity_by_stage_plan({})).to include( @@ -226,7 +294,10 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do projects: 2, todos: 2, service_desk_enabled_projects: 2, - service_desk_issues: 2 + service_desk_issues: 2, + projects_jira_active: 2, + projects_jira_dvcs_cloud_active: 2, + projects_jira_dvcs_server_active: 2 ) expect(described_class.usage_activity_by_stage_plan(described_class.last_28_days_time_period)).to include( issues: 2, @@ -234,7 +305,10 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do projects: 1, todos: 1, service_desk_enabled_projects: 1, - service_desk_issues: 1 + service_desk_issues: 1, + projects_jira_active: 1, + projects_jira_dvcs_cloud_active: 1, + projects_jira_dvcs_server_active: 1 ) end end @@ -325,10 +399,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty end - it 'gathers usage counts monthly hash' do - expect(subject[:counts_monthly]).to be_an(Hash) - end - it 'gathers usage counts correctly' do count_data = subject[:counts] @@ -392,6 +462,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(count_data[:clusters_applications_jupyter]).to eq(1) expect(count_data[:clusters_applications_cilium]).to eq(1) expect(count_data[:clusters_management_project]).to eq(1) + expect(count_data[:kubernetes_agents]).to eq(2) + expect(count_data[:kubernetes_agents_with_token]).to eq(1) expect(count_data[:deployments]).to eq(4) expect(count_data[:successful_deployments]).to eq(2) @@ -399,6 +471,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(count_data[:snippets]).to eq(6) expect(count_data[:personal_snippets]).to eq(2) expect(count_data[:project_snippets]).to eq(4) + + expect(count_data[:projects_with_packages]).to eq(2) + expect(count_data[:packages]).to eq(4) end it 'gathers object store usage correctly' do @@ -411,10 +486,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ) end - it 'gathers topology data' do - expect(subject.keys).to include(:topology) - end - context 'with existing container expiration policies' do let_it_be(:disabled) { create(:container_expiration_policy, enabled: false) } let_it_be(:enabled) { create(:container_expiration_policy, enabled: true) } @@ -491,9 +562,16 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(counts_monthly[:snippets]).to eq(3) expect(counts_monthly[:personal_snippets]).to eq(1) expect(counts_monthly[:project_snippets]).to eq(2) + expect(counts_monthly[:packages]).to eq(3) end end + describe '.usage_counters' do + subject { described_class.usage_counters } + + it { is_expected.to include(:kubernetes_agent_gitops_sync) } + end + describe '.usage_data_counters' do subject { described_class.usage_data_counters } @@ -592,6 +670,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(subject[:git][:version]).to eq(Gitlab::Git.version) expect(subject[:database][:adapter]).to eq(Gitlab::Database.adapter_name) expect(subject[:database][:version]).to eq(Gitlab::Database.version) + expect(subject[:mail][:smtp_server]).to eq(ActionMailer::Base.smtp_settings[:address]) expect(subject[:gitaly][:version]).to be_present expect(subject[:gitaly][:servers]).to be >= 1 expect(subject[:gitaly][:clusters]).to be >= 0 @@ -878,24 +957,25 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do end end - describe '.merge_requests_users' do - let(:time_period) { { created_at: 2.days.ago..Time.current } } - let(:merge_request) { create(:merge_request) } - let(:other_user) { create(:user) } - let(:another_user) { create(:user) } + describe '.merge_requests_users', :clean_gitlab_redis_shared_state do + let(:time_period) { { created_at: 2.days.ago..time } } + let(:time) { Time.current } before do - create(:event, target: merge_request, author: merge_request.author, created_at: 1.day.ago) - create(:event, target: merge_request, author: merge_request.author, created_at: 1.hour.ago) - create(:event, target: merge_request, author: merge_request.author, created_at: 3.days.ago) - create(:event, target: merge_request, author: other_user, created_at: 1.day.ago) - create(:event, target: merge_request, author: other_user, created_at: 1.hour.ago) - create(:event, target: merge_request, author: other_user, created_at: 3.days.ago) - create(:event, target: merge_request, author: another_user, created_at: 4.days.ago) + counter = Gitlab::UsageDataCounters::TrackUniqueEvents + merge_request = Event::TARGET_TYPES[:merge_request] + design = Event::TARGET_TYPES[:design] + + counter.track_event(event_action: :commented, event_target: merge_request, author_id: 1, time: time) + counter.track_event(event_action: :opened, event_target: merge_request, author_id: 1, time: time) + counter.track_event(event_action: :merged, event_target: merge_request, author_id: 2, time: time) + counter.track_event(event_action: :closed, event_target: merge_request, author_id: 3, time: time) + counter.track_event(event_action: :opened, event_target: merge_request, author_id: 4, time: time - 3.days) + counter.track_event(event_action: :created, event_target: design, author_id: 5, time: time) end it 'returns the distinct count of users using merge requests (via events table) within the specified time period' do - expect(described_class.merge_requests_users(time_period)).to eq(2) + expect(described_class.merge_requests_users(time_period)).to eq(3) end end @@ -910,9 +990,12 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do describe '#action_monthly_active_users', :clean_gitlab_redis_shared_state do let(:time_period) { { created_at: 2.days.ago..time } } let(:time) { Time.zone.now } + let(:user1) { build(:user, id: 1) } + let(:user2) { build(:user, id: 2) } + let(:user3) { build(:user, id: 3) } before do - counter = Gitlab::UsageDataCounters::TrackUniqueActions + counter = Gitlab::UsageDataCounters::TrackUniqueEvents project = Event::TARGET_TYPES[:project] wiki = Event::TARGET_TYPES[:wiki] design = Event::TARGET_TYPES[:design] @@ -922,9 +1005,22 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do counter.track_event(event_action: :pushed, event_target: project, author_id: 2) counter.track_event(event_action: :pushed, event_target: project, author_id: 3) counter.track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days) - counter.track_event(event_action: :created, event_target: project, author_id: 5, time: time - 3.days) counter.track_event(event_action: :created, event_target: wiki, author_id: 3) counter.track_event(event_action: :created, event_target: design, author_id: 3) + + counter = Gitlab::UsageDataCounters::EditorUniqueCounter + + counter.track_web_ide_edit_action(author: user1) + counter.track_web_ide_edit_action(author: user1) + counter.track_sfe_edit_action(author: user1) + counter.track_snippet_editor_edit_action(author: user1) + counter.track_snippet_editor_edit_action(author: user1, time: time - 3.days) + + counter.track_web_ide_edit_action(author: user2) + counter.track_sfe_edit_action(author: user2) + + counter.track_web_ide_edit_action(author: user3, time: time - 3.days) + counter.track_snippet_editor_edit_action(author: user3) end it 'returns the distinct count of user actions within the specified time period' do @@ -932,7 +1028,11 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do { action_monthly_active_users_design_management: 1, action_monthly_active_users_project_repo: 3, - action_monthly_active_users_wiki_repo: 1 + action_monthly_active_users_wiki_repo: 1, + action_monthly_active_users_web_ide_edit: 2, + action_monthly_active_users_sfe_edit: 2, + action_monthly_active_users_snippet_editor_edit: 2, + action_monthly_active_users_ide_edit: 3 } ) end @@ -942,8 +1042,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do subject { described_class.analytics_unique_visits_data } it 'returns the number of unique visits to pages with analytics features' do - ::Gitlab::Analytics::UniqueVisits.analytics_ids.each do |target_id| - expect_any_instance_of(::Gitlab::Analytics::UniqueVisits).to receive(:unique_visits_for).with(targets: target_id).and_return(123) + ::Gitlab::Analytics::UniqueVisits.analytics_events.each do |target| + expect_any_instance_of(::Gitlab::Analytics::UniqueVisits).to receive(:unique_visits_for).with(targets: target).and_return(123) end expect_any_instance_of(::Gitlab::Analytics::UniqueVisits).to receive(:unique_visits_for).with(targets: :analytics).and_return(543) @@ -964,6 +1064,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do 'p_analytics_repo' => 123, 'i_analytics_cohorts' => 123, 'i_analytics_dev_ops_score' => 123, + 'i_analytics_instance_statistics' => 123, + 'p_analytics_merge_request' => 123, + 'g_analytics_merge_request' => 123, 'analytics_unique_visits_for_any_target' => 543, 'analytics_unique_visits_for_any_target_monthly' => 987 } @@ -978,8 +1081,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do described_class.clear_memoization(:unique_visit_service) allow_next_instance_of(::Gitlab::Analytics::UniqueVisits) do |instance| - ::Gitlab::Analytics::UniqueVisits.compliance_ids.each do |target_id| - allow(instance).to receive(:unique_visits_for).with(targets: target_id).and_return(123) + ::Gitlab::Analytics::UniqueVisits.compliance_events.each do |target| + allow(instance).to receive(:unique_visits_for).with(targets: target).and_return(123) end allow(instance).to receive(:unique_visits_for).with(targets: :compliance).and_return(543) @@ -995,6 +1098,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do 'g_compliance_audit_events' => 123, 'i_compliance_credential_inventory' => 123, 'i_compliance_audit_events' => 123, + 'a_compliance_audit_events_api' => 123, 'compliance_unique_visits_for_any_target' => 543, 'compliance_unique_visits_for_any_target_monthly' => 987 } @@ -1002,6 +1106,55 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do end end + describe '.search_unique_visits_data' do + subject { described_class.search_unique_visits_data } + + before do + described_class.clear_memoization(:unique_visit_service) + events = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('search') + events.each do |event| + allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: event, start_date: 7.days.ago.to_date, end_date: Date.current).and_return(123) + end + allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: events, start_date: 7.days.ago.to_date, end_date: Date.current).and_return(543) + allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: events, start_date: 4.weeks.ago.to_date, end_date: Date.current).and_return(987) + end + + it 'returns the number of unique visits to pages with search features' do + expect(subject).to eq({ + search_unique_visits: { + 'i_search_total' => 123, + 'i_search_advanced' => 123, + 'i_search_paid' => 123, + 'search_unique_visits_for_any_target_weekly' => 543, + 'search_unique_visits_for_any_target_monthly' => 987 + } + }) + end + end + + describe 'redis_hll_counters' do + subject { described_class.redis_hll_counters } + + let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories } + let(:ineligible_total_categories) { ['source_code'] } + + it 'has all know_events' do + expect(subject).to have_key(:redis_hll_counters) + + expect(subject[:redis_hll_counters].keys).to match_array(categories) + + categories.each do |category| + keys = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category(category) + + if ineligible_total_categories.exclude?(category) + keys.append("#{category}_total_unique_counts_weekly", "#{category}_total_unique_counts_monthly") + end + + expect(subject[:redis_hll_counters][category].keys).to match_array(keys) + end + end + end + describe '.service_desk_counts' do subject { described_class.send(:service_desk_counts) } @@ -1014,4 +1167,46 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do service_desk_issues: 2) end end + + describe '.snowplow_event_counts' do + context 'when self-monitoring project exists' do + let_it_be(:project) { create(:project) } + + before do + stub_application_setting(self_monitoring_project: project) + end + + context 'and product_analytics FF is enabled for it' do + before do + stub_feature_flags(product_analytics: project) + + create(:product_analytics_event, project: project, se_category: 'epics', se_action: 'promote') + create(:product_analytics_event, project: project, se_category: 'epics', se_action: 'promote', collector_tstamp: 28.days.ago) + end + + it 'returns promoted_issues for the time period' do + expect(described_class.snowplow_event_counts[:promoted_issues]).to eq(2) + expect(described_class.snowplow_event_counts( + time_period: described_class.last_28_days_time_period(column: :collector_tstamp) + )[:promoted_issues]).to eq(1) + end + end + + context 'and product_analytics FF is disabled' do + before do + stub_feature_flags(product_analytics: false) + end + + it 'returns an empty hash' do + expect(described_class.snowplow_event_counts).to eq({}) + end + end + end + + context 'when self-monitoring project does not exist' do + it 'returns an empty hash' do + expect(described_class.snowplow_event_counts).to eq({}) + end + end + end end |