Commit 9690e747 authored by Alper Akgun's avatar Alper Akgun Committed by Bob Van Landuyt

Remove feature flag for usage ping batch counter

- Was default on (true) on all environments
- Was well tested past 3 months not to cause any problems
parent 9149d54a
......@@ -283,443 +283,435 @@ RSpec.describe Gitlab::UsageData do
end
end
[true, false].each do |usage_ping_batch_counter_on|
describe "when the feature flag usage_ping_batch_counter is set to #{usage_ping_batch_counter_on}" do
before do
stub_feature_flags(usage_ping_batch_counter: usage_ping_batch_counter_on)
describe '.uncached_data' do
describe '.usage_activity_by_stage' do
it 'includes usage_activity_by_stage data' do
expect(described_class.uncached_data).to include(:usage_activity_by_stage)
expect(described_class.uncached_data).to include(:usage_activity_by_stage_monthly)
end
describe '.uncached_data' do
describe '.usage_activity_by_stage' do
it 'includes usage_activity_by_stage data' do
expect(described_class.uncached_data).to include(:usage_activity_by_stage)
expect(described_class.uncached_data).to include(:usage_activity_by_stage_monthly)
context 'for configure' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
cluster = create(:cluster, user: user)
project = create(:project, creator: user)
create(:clusters_applications_cert_manager, :installed, cluster: cluster)
create(:clusters_applications_helm, :installed, cluster: cluster)
create(:clusters_applications_ingress, :installed, cluster: cluster)
create(:clusters_applications_knative, :installed, cluster: cluster)
create(:cluster, :disabled, user: user)
create(:cluster_provider_gcp, :created)
create(:cluster_provider_aws, :created)
create(:cluster_platform_kubernetes)
create(:cluster, :group, :disabled, user: user)
create(:cluster, :group, user: user)
create(:cluster, :instance, :disabled, :production_environment)
create(:cluster, :instance, :production_environment)
create(:cluster, :management_project)
create(:slack_service, project: project)
create(:slack_slash_commands_service, project: project)
create(:prometheus_service, project: project)
end
context 'for configure' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
cluster = create(:cluster, user: user)
project = create(:project, creator: user)
create(:clusters_applications_cert_manager, :installed, cluster: cluster)
create(:clusters_applications_helm, :installed, cluster: cluster)
create(:clusters_applications_ingress, :installed, cluster: cluster)
create(:clusters_applications_knative, :installed, cluster: cluster)
create(:cluster, :disabled, user: user)
create(:cluster_provider_gcp, :created)
create(:cluster_provider_aws, :created)
create(:cluster_platform_kubernetes)
create(:cluster, :group, :disabled, user: user)
create(:cluster, :group, user: user)
create(:cluster, :instance, :disabled, :production_environment)
create(:cluster, :instance, :production_environment)
create(:cluster, :management_project)
create(:slack_service, project: project)
create(:slack_slash_commands_service, project: project)
create(:prometheus_service, project: project)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:configure]).to eq(
clusters_applications_cert_managers: 2,
clusters_applications_helm: 2,
clusters_applications_ingress: 2,
clusters_applications_knative: 2,
clusters_management_project: 2,
clusters_disabled: 4,
clusters_enabled: 12,
clusters_platforms_gke: 2,
clusters_platforms_eks: 2,
clusters_platforms_user: 2,
instance_clusters_disabled: 2,
instance_clusters_enabled: 2,
group_clusters_disabled: 2,
group_clusters_enabled: 2,
project_clusters_disabled: 2,
project_clusters_enabled: 10,
projects_slack_notifications_active: 2,
projects_slack_slash_active: 2,
projects_with_prometheus_alerts: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:configure]).to eq(
clusters_applications_cert_managers: 1,
clusters_applications_helm: 1,
clusters_applications_ingress: 1,
clusters_applications_knative: 1,
clusters_management_project: 1,
clusters_disabled: 2,
clusters_enabled: 6,
clusters_platforms_gke: 1,
clusters_platforms_eks: 1,
clusters_platforms_user: 1,
instance_clusters_disabled: 1,
instance_clusters_enabled: 1,
group_clusters_disabled: 1,
group_clusters_enabled: 1,
project_clusters_disabled: 1,
project_clusters_enabled: 5,
projects_slack_notifications_active: 1,
projects_slack_slash_active: 1,
projects_with_prometheus_alerts: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:configure]).to eq(
clusters_applications_cert_managers: 2,
clusters_applications_helm: 2,
clusters_applications_ingress: 2,
clusters_applications_knative: 2,
clusters_management_project: 2,
clusters_disabled: 4,
clusters_enabled: 12,
clusters_platforms_gke: 2,
clusters_platforms_eks: 2,
clusters_platforms_user: 2,
instance_clusters_disabled: 2,
instance_clusters_enabled: 2,
group_clusters_disabled: 2,
group_clusters_enabled: 2,
project_clusters_disabled: 2,
project_clusters_enabled: 10,
projects_slack_notifications_active: 2,
projects_slack_slash_active: 2,
projects_with_prometheus_alerts: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:configure]).to eq(
clusters_applications_cert_managers: 1,
clusters_applications_helm: 1,
clusters_applications_ingress: 1,
clusters_applications_knative: 1,
clusters_management_project: 1,
clusters_disabled: 2,
clusters_enabled: 6,
clusters_platforms_gke: 1,
clusters_platforms_eks: 1,
clusters_platforms_user: 1,
instance_clusters_disabled: 1,
instance_clusters_enabled: 1,
group_clusters_disabled: 1,
group_clusters_enabled: 1,
project_clusters_disabled: 1,
project_clusters_enabled: 5,
projects_slack_notifications_active: 1,
projects_slack_slash_active: 1,
projects_with_prometheus_alerts: 1
)
end
end
context 'for create' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
project = create(:project, :repository_private, :github_imported,
:test_repo, :remote_mirror, creator: user)
merge_request = create(:merge_request, source_project: project)
create(:deploy_key, user: user)
create(:key, user: user)
create(:project, creator: user)
create(:protected_branch, project: project)
create(:remote_mirror, project: project)
create(:snippet, author: user)
create(:suggestion, note: create(:note, project: project))
create(:code_owner_rule, merge_request: merge_request, approvals_required: 3)
create(:code_owner_rule, merge_request: merge_request, approvals_required: 7)
create_list(:code_owner_rule, 3, approvals_required: 2)
create_list(:code_owner_rule, 2)
end
context 'for create' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
project = create(:project, :repository_private, :github_imported,
:test_repo, :remote_mirror, creator: user)
merge_request = create(:merge_request, source_project: project)
create(:deploy_key, user: user)
create(:key, user: user)
create(:project, creator: user)
create(:protected_branch, project: project)
create(:remote_mirror, project: project)
create(:snippet, author: user)
create(:suggestion, note: create(:note, project: project))
create(:code_owner_rule, merge_request: merge_request, approvals_required: 3)
create(:code_owner_rule, merge_request: merge_request, approvals_required: 7)
create_list(:code_owner_rule, 3, approvals_required: 2)
create_list(:code_owner_rule, 2)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:create]).to eq(
deploy_keys: 2,
keys: 2,
merge_requests: 12,
projects_enforcing_code_owner_approval: 0,
merge_requests_with_optional_codeowners: 4,
merge_requests_with_required_codeowners: 8,
projects_imported_from_github: 2,
projects_with_repositories_enabled: 12,
protected_branches: 2,
remote_mirrors: 2,
snippets: 2,
suggestions: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:create]).to eq(
deploy_keys: 1,
keys: 1,
merge_requests: 6,
projects_enforcing_code_owner_approval: 0,
merge_requests_with_optional_codeowners: 2,
merge_requests_with_required_codeowners: 4,
projects_imported_from_github: 1,
projects_with_repositories_enabled: 6,
protected_branches: 1,
remote_mirrors: 1,
snippets: 1,
suggestions: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:create]).to eq(
deploy_keys: 2,
keys: 2,
merge_requests: 12,
projects_enforcing_code_owner_approval: 0,
merge_requests_with_optional_codeowners: 4,
merge_requests_with_required_codeowners: 8,
projects_imported_from_github: 2,
projects_with_repositories_enabled: 12,
protected_branches: 2,
remote_mirrors: 2,
snippets: 2,
suggestions: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:create]).to eq(
deploy_keys: 1,
keys: 1,
merge_requests: 6,
projects_enforcing_code_owner_approval: 0,
merge_requests_with_optional_codeowners: 2,
merge_requests_with_required_codeowners: 4,
projects_imported_from_github: 1,
projects_with_repositories_enabled: 6,
protected_branches: 1,
remote_mirrors: 1,
snippets: 1,
suggestions: 1
)
end
end
context 'for manage' do
it 'includes accurate usage_activity_by_stage data' do
stub_config(
ldap:
{ enabled: true, servers: ldap_server_config },
omniauth:
{ providers: omniauth_providers }
)
for_defined_days_back do
user = create(:user)
create(:event, author: user)
create(:group_member, user: user)
create(:key, type: 'LDAPKey', user: user)
create(:group_member, ldap: true, user: user)
create(:cycle_analytics_group_stage)
create(:compliance_framework_project_setting)
end
context 'for manage' do
it 'includes accurate usage_activity_by_stage data' do
stub_config(
ldap:
{ enabled: true, servers: ldap_server_config },
omniauth:
{ providers: omniauth_providers }
)
for_defined_days_back do
user = create(:user)
create(:event, author: user)
create(:group_member, user: user)
create(:key, type: 'LDAPKey', user: user)
create(:group_member, ldap: true, user: user)
create(:cycle_analytics_group_stage)
create(:compliance_framework_project_setting)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:manage]).to eq(
events: 2,
groups: 2,
ldap_keys: 2,
ldap_users: 2,
users_created: 8,
value_stream_management_customized_group_stages: 2,
projects_with_compliance_framework: 2,
ldap_servers: 2,
ldap_group_sync_enabled: true,
ldap_admin_sync_enabled: true,
omniauth_providers: ['google_oauth2'],
group_saml_enabled: true
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:manage]).to eq(
events: 1,
groups: 1,
ldap_keys: 1,
ldap_users: 1,
users_created: 5,
value_stream_management_customized_group_stages: 2,
projects_with_compliance_framework: 2,
ldap_servers: 2,
ldap_group_sync_enabled: true,
ldap_admin_sync_enabled: true,
omniauth_providers: ['google_oauth2'],
group_saml_enabled: true
)
end
def omniauth_providers
[
OpenStruct.new(name: 'google_oauth2'),
OpenStruct.new(name: 'ldapmain'),
OpenStruct.new(name: 'group_saml')
]
end
def ldap_server_config
expect(described_class.uncached_data[:usage_activity_by_stage][:manage]).to eq(
events: 2,
groups: 2,
ldap_keys: 2,
ldap_users: 2,
users_created: 8,
value_stream_management_customized_group_stages: 2,
projects_with_compliance_framework: 2,
ldap_servers: 2,
ldap_group_sync_enabled: true,
ldap_admin_sync_enabled: true,
omniauth_providers: ['google_oauth2'],
group_saml_enabled: true
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:manage]).to eq(
events: 1,
groups: 1,
ldap_keys: 1,
ldap_users: 1,
users_created: 5,
value_stream_management_customized_group_stages: 2,
projects_with_compliance_framework: 2,
ldap_servers: 2,
ldap_group_sync_enabled: true,
ldap_admin_sync_enabled: true,
omniauth_providers: ['google_oauth2'],
group_saml_enabled: true
)
end
def omniauth_providers
[
OpenStruct.new(name: 'google_oauth2'),
OpenStruct.new(name: 'ldapmain'),
OpenStruct.new(name: 'group_saml')
]
end
def ldap_server_config
{
'main' =>
{
'provider_name' => 'ldapmain',
'group_base' => 'ou=groups',
'admin_group' => 'my_group'
},
'secondary' =>
{
'main' =>
{
'provider_name' => 'ldapmain',
'group_base' => 'ou=groups',
'admin_group' => 'my_group'
},
'secondary' =>
{
'provider_name' => 'ldapsecondary',
'group_base' => nil,
'admin_group' => nil
}
'provider_name' => 'ldapsecondary',
'group_base' => nil,
'admin_group' => nil
}
end
}
end
end
context 'for monitor' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user, dashboard: 'operations')
cluster = create(:cluster, user: user)
project = create(:project, creator: user)
create(:clusters_applications_prometheus, :installed, cluster: cluster)
create(:users_ops_dashboard_project, user: user)
create(:prometheus_service, project: project)
create(:project_error_tracking_setting, project: project)
create(:project_tracing_setting, project: project)
end
context 'for monitor' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user, dashboard: 'operations')
cluster = create(:cluster, user: user)
project = create(:project, creator: user)
create(:clusters_applications_prometheus, :installed, cluster: cluster)
create(:users_ops_dashboard_project, user: user)
create(:prometheus_service, project: project)
create(:project_error_tracking_setting, project: project)
create(:project_tracing_setting, project: project)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:monitor]).to eq(
clusters: 2,
clusters_applications_prometheus: 2,
operations_dashboard_default_dashboard: 2,
operations_dashboard_users_with_projects_added: 2,
projects_prometheus_active: 2,
projects_with_error_tracking_enabled: 2,
projects_with_tracing_enabled: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:monitor]).to eq(
clusters: 1,
clusters_applications_prometheus: 1,
operations_dashboard_default_dashboard: 1,
operations_dashboard_users_with_projects_added: 1,
projects_prometheus_active: 1,
projects_with_error_tracking_enabled: 1,
projects_with_tracing_enabled: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:monitor]).to eq(
clusters: 2,
clusters_applications_prometheus: 2,
operations_dashboard_default_dashboard: 2,
operations_dashboard_users_with_projects_added: 2,
projects_prometheus_active: 2,
projects_with_error_tracking_enabled: 2,
projects_with_tracing_enabled: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:monitor]).to eq(
clusters: 1,
clusters_applications_prometheus: 1,
operations_dashboard_default_dashboard: 1,
operations_dashboard_users_with_projects_added: 1,
projects_prometheus_active: 1,
projects_with_error_tracking_enabled: 1,
projects_with_tracing_enabled: 1
)
end
end
context 'for package' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
create(:project, packages: [create(:package)] )
end
context 'for 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.uncached_data[:usage_activity_by_stage][:package]).to eq(
projects_with_packages: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:package]).to eq(
projects_with_packages: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:package]).to eq(
projects_with_packages: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:package]).to eq(
projects_with_packages: 1
)
end
end
context 'for plan' do
it 'includes accurate usage_activity_by_stage data' do
stub_licensed_features(board_assignee_lists: true, board_milestone_lists: true)
for_defined_days_back do
user = create(:user)
project = create(:project, creator: user)
issue = create(:issue, project: project, author: User.support_bot)
create(:issue, project: project, author: user)
board = create(:board, project: project)
create(:user_list, board: board, user: user)
create(:milestone_list, board: board, milestone: create(:milestone, project: project), user: user)
create(:list, board: board, label: create(:label, project: project), user: user)
create(:note, project: project, noteable: issue, author: user)
create(:epic, 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
context 'for plan' do
it 'includes accurate usage_activity_by_stage data' do
stub_licensed_features(board_assignee_lists: true, board_milestone_lists: true)
for_defined_days_back do
user = create(:user)
project = create(:project, creator: user)
issue = create(:issue, project: project, author: User.support_bot)
create(:issue, project: project, author: user)
board = create(:board, project: project)
create(:user_list, board: board, user: user)
create(:milestone_list, board: board, milestone: create(:milestone, project: project), user: user)
create(:list, board: board, label: create(:label, project: project), user: user)
create(:note, project: project, noteable: issue, author: user)
create(:epic, 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.uncached_data[:usage_activity_by_stage][:plan]).to eq(
assignee_lists: 2,
epics: 2,
issues: 3,
label_lists: 2,
milestone_lists: 2,
notes: 2,
projects: 2,
projects_jira_active: 2,
projects_jira_dvcs_cloud_active: 2,
projects_jira_dvcs_server_active: 2,
service_desk_enabled_projects: 2,
service_desk_issues: 2,
todos: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:plan]).to eq(
assignee_lists: 1,
epics: 1,
issues: 2,
label_lists: 1,
milestone_lists: 1,
notes: 1,
projects: 1,
projects_jira_active: 1,
projects_jira_dvcs_cloud_active: 1,
projects_jira_dvcs_server_active: 1,
service_desk_enabled_projects: 1,
service_desk_issues: 1,
todos: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:plan]).to eq(
assignee_lists: 2,
epics: 2,
issues: 3,
label_lists: 2,
milestone_lists: 2,
notes: 2,
projects: 2,
projects_jira_active: 2,
projects_jira_dvcs_cloud_active: 2,
projects_jira_dvcs_server_active: 2,
service_desk_enabled_projects: 2,
service_desk_issues: 2,
todos: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:plan]).to eq(
assignee_lists: 1,
epics: 1,
issues: 2,
label_lists: 1,
milestone_lists: 1,
notes: 1,
projects: 1,
projects_jira_active: 1,
projects_jira_dvcs_cloud_active: 1,
projects_jira_dvcs_server_active: 1,
service_desk_enabled_projects: 1,
service_desk_issues: 1,
todos: 1
)
end
end
context 'for release' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
create(:deployment, :failed, user: user)
create(:project, :mirror, mirror_trigger_builds: true)
create(:release, author: user)
create(:deployment, :success, user: user)
end
context 'for release' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
create(:deployment, :failed, user: user)
create(:project, :mirror, mirror_trigger_builds: true)
create(:release, author: user)
create(:deployment, :success, user: user)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:release]).to eq(
deployments: 2,
failed_deployments: 2,
projects_mirrored_with_pipelines_enabled: 2,
releases: 2,
successful_deployments: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:release]).to eq(
deployments: 1,
failed_deployments: 1,
projects_mirrored_with_pipelines_enabled: 1,
releases: 1,
successful_deployments: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:release]).to eq(
deployments: 2,
failed_deployments: 2,
projects_mirrored_with_pipelines_enabled: 2,
releases: 2,
successful_deployments: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:release]).to eq(
deployments: 1,
failed_deployments: 1,
projects_mirrored_with_pipelines_enabled: 1,
releases: 1,
successful_deployments: 1
)
end
end
context 'for secure' do
let_it_be(:user) { create(:user, group_view: :security_dashboard) }
before do
for_defined_days_back do
create(:ci_build, name: 'container_scanning', user: user)
create(:ci_build, name: 'dast', user: user)
create(:ci_build, name: 'dependency_scanning', user: user)
create(:ci_build, name: 'license_management', user: user)
create(:ci_build, name: 'sast', user: user)
create(:ci_build, name: 'secret_detection', user: user)
end
end
context 'for secure' do
let_it_be(:user) { create(:user, group_view: :security_dashboard) }
before do
for_defined_days_back do
create(:ci_build, name: 'container_scanning', user: user)
create(:ci_build, name: 'dast', user: user)
create(:ci_build, name: 'dependency_scanning', user: user)
create(:ci_build, name: 'license_management', user: user)
create(:ci_build, name: 'sast', user: user)
create(:ci_build, name: 'secret_detection', user: user)
end
end
it 'includes accurate usage_activity_by_stage data' do
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:secure]).to eq(
user_preferences_group_overview_security_dashboard: 1,
user_container_scanning_jobs: 1,
user_dast_jobs: 1,
user_dependency_scanning_jobs: 1,
user_license_management_jobs: 1,
user_sast_jobs: 1,
user_secret_detection_jobs: 1
)
end
it 'combines license_scanning into license_management' do
for_defined_days_back do
create(:ci_build, name: 'license_scanning', user: user)
end
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:secure]).to eq(
user_preferences_group_overview_security_dashboard: 1,
user_container_scanning_jobs: 1,
user_dast_jobs: 1,
user_dependency_scanning_jobs: 1,
user_license_management_jobs: 2,
user_sast_jobs: 1,
user_secret_detection_jobs: 1
)
end
it 'has to resort to 0 for counting license scan' do
allow(Gitlab::Database::BatchCount).to receive(:batch_distinct_count).and_raise(ActiveRecord::StatementInvalid)
allow(::Ci::Build).to receive(:distinct_count_by).and_raise(ActiveRecord::StatementInvalid)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:secure]).to eq(
user_preferences_group_overview_security_dashboard: 1,
user_container_scanning_jobs: -1,
user_dast_jobs: -1,
user_dependency_scanning_jobs: -1,
user_license_management_jobs: -1,
user_sast_jobs: -1,
user_secret_detection_jobs: -1
)
end
it 'includes accurate usage_activity_by_stage data' do
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:secure]).to eq(
user_preferences_group_overview_security_dashboard: 1,
user_container_scanning_jobs: 1,
user_dast_jobs: 1,
user_dependency_scanning_jobs: 1,
user_license_management_jobs: 1,
user_sast_jobs: 1,
user_secret_detection_jobs: 1
)
end
it 'combines license_scanning into license_management' do
for_defined_days_back do
create(:ci_build, name: 'license_scanning', user: user)
end
context 'for verify' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
create(:ci_build, user: user)
create(:ci_empty_pipeline, source: :external, user: user)
create(:ci_empty_pipeline, user: user)
create(:ci_pipeline, :auto_devops_source, user: user)
create(:ci_pipeline, :repository_source, user: user)
create(:ci_pipeline_schedule, owner: user)
create(:ci_trigger, owner: user)
create(:clusters_applications_runner, :installed)
create(:github_service)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:verify]).to eq(
ci_builds: 2,
ci_external_pipelines: 2,
ci_internal_pipelines: 2,
ci_pipeline_config_auto_devops: 2,
ci_pipeline_config_repository: 2,
ci_pipeline_schedules: 2,
ci_pipelines: 2,
ci_triggers: 2,
clusters_applications_runner: 2,
projects_reporting_ci_cd_back_to_github: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:verify]).to eq(
ci_builds: 1,
ci_external_pipelines: 1,
ci_internal_pipelines: 1,
ci_pipeline_config_auto_devops: 1,
ci_pipeline_config_repository: 1,
ci_pipeline_schedules: 1,
ci_pipelines: 1,
ci_triggers: 1,
clusters_applications_runner: 1,
projects_reporting_ci_cd_back_to_github: 1
)
end
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:secure]).to eq(
user_preferences_group_overview_security_dashboard: 1,
user_container_scanning_jobs: 1,
user_dast_jobs: 1,
user_dependency_scanning_jobs: 1,
user_license_management_jobs: 2,
user_sast_jobs: 1,
user_secret_detection_jobs: 1
)
end
it 'has to resort to 0 for counting license scan' do
allow(Gitlab::Database::BatchCount).to receive(:batch_distinct_count).and_raise(ActiveRecord::StatementInvalid)
allow(::Ci::Build).to receive(:distinct_count_by).and_raise(ActiveRecord::StatementInvalid)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:secure]).to eq(
user_preferences_group_overview_security_dashboard: 1,
user_container_scanning_jobs: -1,
user_dast_jobs: -1,
user_dependency_scanning_jobs: -1,
user_license_management_jobs: -1,
user_sast_jobs: -1,
user_secret_detection_jobs: -1
)
end
end
context 'for verify' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
user = create(:user)
create(:ci_build, user: user)
create(:ci_empty_pipeline, source: :external, user: user)
create(:ci_empty_pipeline, user: user)
create(:ci_pipeline, :auto_devops_source, user: user)
create(:ci_pipeline, :repository_source, user: user)
create(:ci_pipeline_schedule, owner: user)
create(:ci_trigger, owner: user)
create(:clusters_applications_runner, :installed)
create(:github_service)
end
expect(described_class.uncached_data[:usage_activity_by_stage][:verify]).to eq(
ci_builds: 2,
ci_external_pipelines: 2,
ci_internal_pipelines: 2,
ci_pipeline_config_auto_devops: 2,
ci_pipeline_config_repository: 2,
ci_pipeline_schedules: 2,
ci_pipelines: 2,
ci_triggers: 2,
clusters_applications_runner: 2,
projects_reporting_ci_cd_back_to_github: 2
)
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:verify]).to eq(
ci_builds: 1,
ci_external_pipelines: 1,
ci_internal_pipelines: 1,
ci_pipeline_config_auto_devops: 1,
ci_pipeline_config_repository: 1,
ci_pipeline_schedules: 1,
ci_pipelines: 1,
ci_triggers: 1,
clusters_applications_runner: 1,
projects_reporting_ci_cd_back_to_github: 1
)
end
end
end
......
......@@ -40,7 +40,7 @@ module Gitlab
FALLBACK = -1
def count(relation, column = nil, batch: true, start: nil, finish: nil)
if batch && Feature.enabled?(:usage_ping_batch_counter, default_enabled: true)
if batch
Gitlab::Database::BatchCount.batch_count(relation, column, start: start, finish: finish)
else
relation.count
......@@ -50,7 +50,7 @@ module Gitlab
end
def distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
if batch && Feature.enabled?(:usage_ping_batch_counter, default_enabled: true)
if batch
Gitlab::Database::BatchCount.batch_distinct_count(relation, column, batch_size: batch_size, start: start, finish: finish)
else
relation.distinct_count_by(column)
......
......@@ -10,656 +10,638 @@ describe Gitlab::UsageData, :aggregate_failures do
stub_object_store_settings
end
shared_examples "usage data execution" do
describe '#data' do
let!(:ud) { build(:usage_data) }
describe '#data' do
let!(:ud) { build(:usage_data) }
before do
allow(described_class).to receive(:grafana_embed_usage_data).and_return(2)
end
before do
allow(described_class).to receive(:grafana_embed_usage_data).and_return(2)
end
subject { described_class.data }
subject { described_class.data }
it 'gathers usage data' do
expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS)
end
it 'gathers usage data' do
expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS)
end
it 'gathers usage counts' do
count_data = subject[:counts]
it 'gathers usage counts' do
count_data = subject[:counts]
expect(count_data[:boards]).to eq(1)
expect(count_data[:projects]).to eq(4)
expect(count_data.values_at(*UsageDataHelpers::SMAU_KEYS)).to all(be_an(Integer))
expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS)
expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty
end
expect(count_data[:boards]).to eq(1)
expect(count_data[:projects]).to eq(4)
expect(count_data.values_at(*UsageDataHelpers::SMAU_KEYS)).to all(be_an(Integer))
expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS)
expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty
end
it 'gathers projects data correctly' do
count_data = subject[:counts]
expect(count_data[:projects]).to eq(4)
expect(count_data[:projects_asana_active]).to eq(0)
expect(count_data[:projects_prometheus_active]).to eq(1)
expect(count_data[:projects_jira_active]).to eq(4)
expect(count_data[:projects_jira_server_active]).to eq(2)
expect(count_data[:projects_jira_cloud_active]).to eq(2)
expect(count_data[:jira_imports_projects_count]).to eq(2)
expect(count_data[:jira_imports_total_imported_count]).to eq(3)
expect(count_data[:jira_imports_total_imported_issues_count]).to eq(13)
expect(count_data[:projects_slack_notifications_active]).to eq(2)
expect(count_data[:projects_slack_slash_active]).to eq(1)
expect(count_data[:projects_slack_active]).to eq(2)
expect(count_data[:projects_slack_slash_commands_active]).to eq(1)
expect(count_data[:projects_custom_issue_tracker_active]).to eq(1)
expect(count_data[:projects_mattermost_active]).to eq(0)
expect(count_data[:projects_with_repositories_enabled]).to eq(3)
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
expect(count_data[:projects_with_alerts_service_enabled]).to eq(1)
expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
expect(count_data[:projects_with_terraform_reports]).to eq(2)
expect(count_data[:projects_with_terraform_states]).to eq(2)
expect(count_data[:terraform_reports]).to eq(3)
expect(count_data[:terraform_states]).to eq(3)
expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1)
expect(count_data[:issues_with_associated_zoom_link]).to eq(2)
expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
expect(count_data[:incident_issues]).to eq(4)
expect(count_data[:issues_created_gitlab_alerts]).to eq(1)
expect(count_data[:alert_bot_incident_issues]).to eq(4)
expect(count_data[:incident_labeled_issues]).to eq(3)
expect(count_data[:clusters_enabled]).to eq(6)
expect(count_data[:project_clusters_enabled]).to eq(4)
expect(count_data[:group_clusters_enabled]).to eq(1)
expect(count_data[:instance_clusters_enabled]).to eq(1)
expect(count_data[:clusters_disabled]).to eq(3)
expect(count_data[:project_clusters_disabled]).to eq(1)
expect(count_data[:group_clusters_disabled]).to eq(1)
expect(count_data[:instance_clusters_disabled]).to eq(1)
expect(count_data[:clusters_platforms_eks]).to eq(1)
expect(count_data[:clusters_platforms_gke]).to eq(1)
expect(count_data[:clusters_platforms_user]).to eq(1)
expect(count_data[:clusters_applications_helm]).to eq(1)
expect(count_data[:clusters_applications_ingress]).to eq(1)
expect(count_data[:clusters_applications_cert_managers]).to eq(1)
expect(count_data[:clusters_applications_crossplane]).to eq(1)
expect(count_data[:clusters_applications_prometheus]).to eq(1)
expect(count_data[:clusters_applications_runner]).to eq(1)
expect(count_data[:clusters_applications_knative]).to eq(1)
expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
expect(count_data[:grafana_integrated_projects]).to eq(2)
expect(count_data[:clusters_applications_jupyter]).to eq(1)
expect(count_data[:clusters_management_project]).to eq(1)
end
it 'gathers projects data correctly' do
count_data = subject[:counts]
expect(count_data[:projects]).to eq(4)
expect(count_data[:projects_asana_active]).to eq(0)
expect(count_data[:projects_prometheus_active]).to eq(1)
expect(count_data[:projects_jira_active]).to eq(4)
expect(count_data[:projects_jira_server_active]).to eq(2)
expect(count_data[:projects_jira_cloud_active]).to eq(2)
expect(count_data[:jira_imports_projects_count]).to eq(2)
expect(count_data[:jira_imports_total_imported_count]).to eq(3)
expect(count_data[:jira_imports_total_imported_issues_count]).to eq(13)
expect(count_data[:projects_slack_notifications_active]).to eq(2)
expect(count_data[:projects_slack_slash_active]).to eq(1)
expect(count_data[:projects_slack_active]).to eq(2)
expect(count_data[:projects_slack_slash_commands_active]).to eq(1)
expect(count_data[:projects_custom_issue_tracker_active]).to eq(1)
expect(count_data[:projects_mattermost_active]).to eq(0)
expect(count_data[:projects_with_repositories_enabled]).to eq(3)
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
expect(count_data[:projects_with_alerts_service_enabled]).to eq(1)
expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
expect(count_data[:projects_with_terraform_reports]).to eq(2)
expect(count_data[:projects_with_terraform_states]).to eq(2)
expect(count_data[:terraform_reports]).to eq(3)
expect(count_data[:terraform_states]).to eq(3)
expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1)
expect(count_data[:issues_with_associated_zoom_link]).to eq(2)
expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
expect(count_data[:incident_issues]).to eq(4)
expect(count_data[:issues_created_gitlab_alerts]).to eq(1)
expect(count_data[:alert_bot_incident_issues]).to eq(4)
expect(count_data[:incident_labeled_issues]).to eq(3)
expect(count_data[:clusters_enabled]).to eq(6)
expect(count_data[:project_clusters_enabled]).to eq(4)
expect(count_data[:group_clusters_enabled]).to eq(1)
expect(count_data[:instance_clusters_enabled]).to eq(1)
expect(count_data[:clusters_disabled]).to eq(3)
expect(count_data[:project_clusters_disabled]).to eq(1)
expect(count_data[:group_clusters_disabled]).to eq(1)
expect(count_data[:instance_clusters_disabled]).to eq(1)
expect(count_data[:clusters_platforms_eks]).to eq(1)
expect(count_data[:clusters_platforms_gke]).to eq(1)
expect(count_data[:clusters_platforms_user]).to eq(1)
expect(count_data[:clusters_applications_helm]).to eq(1)
expect(count_data[:clusters_applications_ingress]).to eq(1)
expect(count_data[:clusters_applications_cert_managers]).to eq(1)
expect(count_data[:clusters_applications_crossplane]).to eq(1)
expect(count_data[:clusters_applications_prometheus]).to eq(1)
expect(count_data[:clusters_applications_runner]).to eq(1)
expect(count_data[:clusters_applications_knative]).to eq(1)
expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
expect(count_data[:grafana_integrated_projects]).to eq(2)
expect(count_data[:clusters_applications_jupyter]).to eq(1)
expect(count_data[:clusters_management_project]).to eq(1)
end
it 'gathers object store usage correctly' do
expect(subject[:object_store]).to eq(
{ artifacts: { enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } },
external_diffs: { enabled: false },
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" } },
packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } }
)
end
it 'gathers object store usage correctly' do
expect(subject[:object_store]).to eq(
{ artifacts: { enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } },
external_diffs: { enabled: false },
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" } },
packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } }
)
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) }
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) }
%i[keep_n cadence older_than].each do |attribute|
ContainerExpirationPolicy.send("#{attribute}_options").keys.each do |value|
let_it_be("container_expiration_policy_with_#{attribute}_set_to_#{value}") { create(:container_expiration_policy, attribute => value) }
end
%i[keep_n cadence older_than].each do |attribute|
ContainerExpirationPolicy.send("#{attribute}_options").keys.each do |value|
let_it_be("container_expiration_policy_with_#{attribute}_set_to_#{value}") { create(:container_expiration_policy, attribute => value) }
end
end
let_it_be('container_expiration_policy_with_keep_n_set_to_null') { create(:container_expiration_policy, keep_n: nil) }
let_it_be('container_expiration_policy_with_older_than_set_to_null') { create(:container_expiration_policy, older_than: nil) }
let(:inactive_policies) { ::ContainerExpirationPolicy.where(enabled: false) }
let(:active_policies) { ::ContainerExpirationPolicy.active }
subject { described_class.data[:counts] }
it 'gathers usage data' do
expect(subject[:projects_with_expiration_policy_enabled]).to eq 22
expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
let_it_be('container_expiration_policy_with_keep_n_set_to_null') { create(:container_expiration_policy, keep_n: nil) }
let_it_be('container_expiration_policy_with_older_than_set_to_null') { create(:container_expiration_policy, older_than: nil) }
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 16
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
let(:inactive_policies) { ::ContainerExpirationPolicy.where(enabled: false) }
let(:active_policies) { ::ContainerExpirationPolicy.active }
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_unset]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 18
subject { described_class.data[:counts] }
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 18
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_3month]).to eq 1
end
it 'gathers usage data' do
expect(subject[:projects_with_expiration_policy_enabled]).to eq 22
expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 16
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_unset]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 18
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 18
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_3month]).to eq 1
end
end
it 'works when queries time out' do
allow_any_instance_of(ActiveRecord::Relation)
.to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
it 'works when queries time out' do
allow_any_instance_of(ActiveRecord::Relation)
.to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
expect { subject }.not_to raise_error
end
expect { subject }.not_to raise_error
end
it 'jira usage works when queries time out' do
allow_any_instance_of(ActiveRecord::Relation)
.to receive(:find_in_batches).and_raise(ActiveRecord::StatementInvalid.new(''))
it 'jira usage works when queries time out' do
allow_any_instance_of(ActiveRecord::Relation)
.to receive(:find_in_batches).and_raise(ActiveRecord::StatementInvalid.new(''))
expect { described_class.jira_usage }.not_to raise_error
end
expect { described_class.jira_usage }.not_to raise_error
end
end
describe '#usage_data_counters' do
subject { described_class.usage_data_counters }
describe '#usage_data_counters' do
subject { described_class.usage_data_counters }
it { is_expected.to all(respond_to :totals) }
it { is_expected.to all(respond_to :fallback_totals) }
it { is_expected.to all(respond_to :totals) }
it { is_expected.to all(respond_to :fallback_totals) }
describe 'the results of calling #totals on all objects in the array' do
subject { described_class.usage_data_counters.map(&:totals) }
describe 'the results of calling #totals on all objects in the array' do
subject { described_class.usage_data_counters.map(&:totals) }
it { is_expected.to all(be_a Hash) }
it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) }
end
it { is_expected.to all(be_a Hash) }
it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) }
end
describe 'the results of calling #fallback_totals on all objects in the array' do
subject { described_class.usage_data_counters.map(&:fallback_totals) }
describe 'the results of calling #fallback_totals on all objects in the array' do
subject { described_class.usage_data_counters.map(&:fallback_totals) }
it { is_expected.to all(be_a Hash) }
it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(eq(-1)))) }
end
it { is_expected.to all(be_a Hash) }
it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(eq(-1)))) }
end
it 'does not have any conflicts' do
all_keys = subject.flat_map { |counter| counter.totals.keys }
it 'does not have any conflicts' do
all_keys = subject.flat_map { |counter| counter.totals.keys }
expect(all_keys.size).to eq all_keys.to_set.size
end
expect(all_keys.size).to eq all_keys.to_set.size
end
end
describe '#license_usage_data' do
subject { described_class.license_usage_data }
describe '#license_usage_data' do
subject { described_class.license_usage_data }
it 'gathers license data' do
expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
expect(subject[:version]).to eq(Gitlab::VERSION)
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)
end
it 'gathers license data' do
expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
expect(subject[:version]).to eq(Gitlab::VERSION)
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)
end
end
describe '.recording_ce_finished_at' do
subject { described_class.recording_ce_finish_data }
describe '.recording_ce_finished_at' do
subject { described_class.recording_ce_finish_data }
it 'gathers time ce recording finishes at' do
expect(subject[:recording_ce_finished_at]).to be_a(Time)
end
it 'gathers time ce recording finishes at' do
expect(subject[:recording_ce_finished_at]).to be_a(Time)
end
end
context 'when not relying on database records' do
describe '#features_usage_data_ce' do
subject { described_class.features_usage_data_ce }
it 'gathers feature usage data' do
expect(subject[:mattermost_enabled]).to eq(Gitlab.config.mattermost.enabled)
expect(subject[:signup_enabled]).to eq(Gitlab::CurrentSettings.allow_signup?)
expect(subject[:ldap_enabled]).to eq(Gitlab.config.ldap.enabled)
expect(subject[:gravatar_enabled]).to eq(Gitlab::CurrentSettings.gravatar_enabled?)
expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?)
expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?)
expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled)
expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled)
expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled)
expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?)
expect(subject[:grafana_link_enabled]).to eq(Gitlab::CurrentSettings.grafana_enabled?)
end
context 'with embedded grafana' do
it 'returns true when embedded grafana is enabled' do
stub_application_setting(grafana_enabled: true)
expect(subject[:grafana_link_enabled]).to eq(true)
end
context 'when not relying on database records' do
describe '#features_usage_data_ce' do
subject { described_class.features_usage_data_ce }
it 'gathers feature usage data' do
expect(subject[:mattermost_enabled]).to eq(Gitlab.config.mattermost.enabled)
expect(subject[:signup_enabled]).to eq(Gitlab::CurrentSettings.allow_signup?)
expect(subject[:ldap_enabled]).to eq(Gitlab.config.ldap.enabled)
expect(subject[:gravatar_enabled]).to eq(Gitlab::CurrentSettings.gravatar_enabled?)
expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?)
expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?)
expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled)
expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled)
expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled)
expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?)
expect(subject[:grafana_link_enabled]).to eq(Gitlab::CurrentSettings.grafana_enabled?)
end
it 'returns false when embedded grafana is disabled' do
stub_application_setting(grafana_enabled: false)
context 'with embedded grafana' do
it 'returns true when embedded grafana is enabled' do
stub_application_setting(grafana_enabled: true)
expect(subject[:grafana_link_enabled]).to eq(false)
end
expect(subject[:grafana_link_enabled]).to eq(true)
end
end
describe '#components_usage_data' do
subject { described_class.components_usage_data }
it 'gathers basic components usage data' do
stub_runtime(:puma)
it 'returns false when embedded grafana is disabled' do
stub_application_setting(grafana_enabled: false)
expect(subject[:app_server][:type]).to eq('puma')
expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled)
expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION)
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[:gitaly][:version]).to be_present
expect(subject[:gitaly][:servers]).to be >= 1
expect(subject[:gitaly][:clusters]).to be >= 0
expect(subject[:gitaly][:filesystems]).to be_an(Array)
expect(subject[:gitaly][:filesystems].first).to be_a(String)
expect(subject[:grafana_link_enabled]).to eq(false)
end
end
end
def stub_runtime(runtime)
allow(Gitlab::Runtime).to receive(:identify).and_return(runtime)
end
describe '#components_usage_data' do
subject { described_class.components_usage_data }
it 'gathers basic components usage data' do
stub_runtime(:puma)
expect(subject[:app_server][:type]).to eq('puma')
expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled)
expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION)
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[:gitaly][:version]).to be_present
expect(subject[:gitaly][:servers]).to be >= 1
expect(subject[:gitaly][:clusters]).to be >= 0
expect(subject[:gitaly][:filesystems]).to be_an(Array)
expect(subject[:gitaly][:filesystems].first).to be_a(String)
end
describe '#topology_usage_data' do
subject { described_class.topology_usage_data }
def stub_runtime(runtime)
allow(Gitlab::Runtime).to receive(:identify).and_return(runtime)
end
end
describe '#topology_usage_data' do
subject { described_class.topology_usage_data }
before do
# this pins down time shifts when benchmarking durations
allow(Process).to receive(:clock_gettime).and_return(0)
end
context 'when embedded Prometheus server is enabled' do
before do
# this pins down time shifts when benchmarking durations
allow(Process).to receive(:clock_gettime).and_return(0)
expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(true)
expect(Gitlab::Prometheus::Internal).to receive(:uri).and_return('http://prom:9090')
end
context 'when embedded Prometheus server is enabled' do
before do
expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(true)
expect(Gitlab::Prometheus::Internal).to receive(:uri).and_return('http://prom:9090')
end
it 'contains a topology element' do
allow_prometheus_queries
it 'contains a topology element' do
allow_prometheus_queries
expect(subject).to have_key(:topology)
end
expect(subject).to have_key(:topology)
end
context 'tracking node metrics' do
it 'contains node level metrics for each instance' do
expect_prometheus_api_to receive(:aggregate)
.with(func: 'avg', metric: 'node_memory_MemTotal_bytes', by: 'instance')
.and_return({
'instance1' => 512,
'instance2' => 1024
})
expect(subject[:topology]).to eq({
duration_s: 0,
nodes: [
{
node_memory_total_bytes: 512
},
{
node_memory_total_bytes: 1024
}
]
context 'tracking node metrics' do
it 'contains node level metrics for each instance' do
expect_prometheus_api_to receive(:aggregate)
.with(func: 'avg', metric: 'node_memory_MemTotal_bytes', by: 'instance')
.and_return({
'instance1' => 512,
'instance2' => 1024
})
end
end
context 'and no results are found' do
it 'does not report anything' do
expect_prometheus_api_to receive(:aggregate).and_return({})
expect(subject[:topology]).to eq({
duration_s: 0,
nodes: []
})
end
expect(subject[:topology]).to eq({
duration_s: 0,
nodes: [
{
node_memory_total_bytes: 512
},
{
node_memory_total_bytes: 1024
}
]
})
end
end
context 'and a connection error is raised' do
it 'does not report anything' do
expect_prometheus_api_to receive(:aggregate).and_raise('Connection failed')
context 'and no results are found' do
it 'does not report anything' do
expect_prometheus_api_to receive(:aggregate).and_return({})
expect(subject[:topology]).to eq({ duration_s: 0 })
end
expect(subject[:topology]).to eq({
duration_s: 0,
nodes: []
})
end
end
context 'when embedded Prometheus server is disabled' do
context 'and a connection error is raised' do
it 'does not report anything' do
expect_prometheus_api_to receive(:aggregate).and_raise('Connection failed')
expect(subject[:topology]).to eq({ duration_s: 0 })
end
end
end
def expect_prometheus_api_to(receive_matcher)
expect_next_instance_of(Gitlab::PrometheusClient) do |client|
expect(client).to receive_matcher
end
context 'when embedded Prometheus server is disabled' do
it 'does not report anything' do
expect(subject[:topology]).to eq({ duration_s: 0 })
end
end
def allow_prometheus_queries
allow_next_instance_of(Gitlab::PrometheusClient) do |client|
allow(client).to receive(:aggregate).and_return({})
end
def expect_prometheus_api_to(receive_matcher)
expect_next_instance_of(Gitlab::PrometheusClient) do |client|
expect(client).to receive_matcher
end
end
describe '#app_server_type' do
subject { described_class.app_server_type }
def allow_prometheus_queries
allow_next_instance_of(Gitlab::PrometheusClient) do |client|
allow(client).to receive(:aggregate).and_return({})
end
end
end
it 'successfully identifies runtime and returns the identifier' do
expect(Gitlab::Runtime).to receive(:identify).and_return(:runtime_identifier)
describe '#app_server_type' do
subject { described_class.app_server_type }
is_expected.to eq('runtime_identifier')
end
it 'successfully identifies runtime and returns the identifier' do
expect(Gitlab::Runtime).to receive(:identify).and_return(:runtime_identifier)
context 'when runtime is not identified' do
let(:exception) { Gitlab::Runtime::IdentificationError.new('exception message from runtime identify') }
is_expected.to eq('runtime_identifier')
end
it 'logs the exception and returns unknown app server type' do
expect(Gitlab::Runtime).to receive(:identify).and_raise(exception)
context 'when runtime is not identified' do
let(:exception) { Gitlab::Runtime::IdentificationError.new('exception message from runtime identify') }
expect(Gitlab::AppLogger).to receive(:error).with(exception.message)
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(exception)
expect(subject).to eq('unknown_app_server_type')
end
it 'logs the exception and returns unknown app server type' do
expect(Gitlab::Runtime).to receive(:identify).and_raise(exception)
expect(Gitlab::AppLogger).to receive(:error).with(exception.message)
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(exception)
expect(subject).to eq('unknown_app_server_type')
end
end
end
describe '#object_store_config' do
let(:component) { 'lfs' }
describe '#object_store_config' do
let(:component) { 'lfs' }
subject { described_class.object_store_config(component) }
subject { described_class.object_store_config(component) }
context 'when object_store is not configured' do
it 'returns component enable status only' do
allow(Settings).to receive(:[]).with(component).and_return({ 'enabled' => false })
context 'when object_store is not configured' do
it 'returns component enable status only' do
allow(Settings).to receive(:[]).with(component).and_return({ 'enabled' => false })
expect(subject).to eq({ enabled: false })
end
expect(subject).to eq({ enabled: false })
end
end
context 'when object_store is configured' do
it 'returns filtered object store config' do
allow(Settings).to receive(:[]).with(component)
.and_return(
context 'when object_store is configured' do
it 'returns filtered object store config' do
allow(Settings).to receive(:[]).with(component)
.and_return(
{ 'enabled' => true,
'object_store' =>
{ 'enabled' => true,
'object_store' =>
{ 'enabled' => true,
'remote_directory' => component,
'direct_upload' => true,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => false,
'proxy_download' => false } })
expect(subject).to eq(
{ enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } })
end
'remote_directory' => component,
'direct_upload' => true,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => false,
'proxy_download' => false } })
expect(subject).to eq(
{ enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } })
end
end
context 'when retrieve component setting meets exception' do
it 'returns -1 for component enable status' do
allow(Settings).to receive(:[]).with(component).and_raise(StandardError)
context 'when retrieve component setting meets exception' do
it 'returns -1 for component enable status' do
allow(Settings).to receive(:[]).with(component).and_raise(StandardError)
expect(subject).to eq({ enabled: -1 })
end
expect(subject).to eq({ enabled: -1 })
end
end
end
describe '#object_store_usage_data' do
subject { described_class.object_store_usage_data }
it 'fetches object store config of five components' do
%w(artifacts external_diffs lfs uploads packages).each do |component|
expect(described_class).to receive(:object_store_config).with(component).and_return("#{component}_object_store_config")
end
describe '#object_store_usage_data' do
subject { described_class.object_store_usage_data }
expect(subject).to eq(
object_store: {
artifacts: 'artifacts_object_store_config',
external_diffs: 'external_diffs_object_store_config',
lfs: 'lfs_object_store_config',
uploads: 'uploads_object_store_config',
packages: 'packages_object_store_config'
})
it 'fetches object store config of five components' do
%w(artifacts external_diffs lfs uploads packages).each do |component|
expect(described_class).to receive(:object_store_config).with(component).and_return("#{component}_object_store_config")
end
expect(subject).to eq(
object_store: {
artifacts: 'artifacts_object_store_config',
external_diffs: 'external_diffs_object_store_config',
lfs: 'lfs_object_store_config',
uploads: 'uploads_object_store_config',
packages: 'packages_object_store_config'
})
end
end
describe '#cycle_analytics_usage_data' do
subject { described_class.cycle_analytics_usage_data }
describe '#cycle_analytics_usage_data' do
subject { described_class.cycle_analytics_usage_data }
it 'works when queries time out in new' do
allow(Gitlab::CycleAnalytics::UsageData)
.to receive(:new).and_raise(ActiveRecord::StatementInvalid.new(''))
it 'works when queries time out in new' do
allow(Gitlab::CycleAnalytics::UsageData)
.to receive(:new).and_raise(ActiveRecord::StatementInvalid.new(''))
expect { subject }.not_to raise_error
end
expect { subject }.not_to raise_error
end
it 'works when queries time out in to_json' do
allow_any_instance_of(Gitlab::CycleAnalytics::UsageData)
.to receive(:to_json).and_raise(ActiveRecord::StatementInvalid.new(''))
it 'works when queries time out in to_json' do
allow_any_instance_of(Gitlab::CycleAnalytics::UsageData)
.to receive(:to_json).and_raise(ActiveRecord::StatementInvalid.new(''))
expect { subject }.not_to raise_error
end
end
expect { subject }.not_to raise_error
describe '#ingress_modsecurity_usage' do
subject { described_class.ingress_modsecurity_usage }
let(:environment) { create(:environment) }
let(:project) { environment.project }
let(:environment_scope) { '*' }
let(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project]) }
let(:ingress_mode) { :modsecurity_blocking }
let!(:ingress) { create(:clusters_applications_ingress, ingress_mode, cluster: cluster) }
context 'when cluster is disabled' do
let(:cluster) { create(:cluster, :disabled, projects: [project]) }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
describe '#ingress_modsecurity_usage' do
subject { described_class.ingress_modsecurity_usage }
context 'when deployment is unsuccessful' do
let!(:deployment) { create(:deployment, :failed, environment: environment, project: project, cluster: cluster) }
let(:environment) { create(:environment) }
let(:project) { environment.project }
let(:environment_scope) { '*' }
let(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project]) }
let(:ingress_mode) { :modsecurity_blocking }
let!(:ingress) { create(:clusters_applications_ingress, ingress_mode, cluster: cluster) }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'when cluster is disabled' do
let(:cluster) { create(:cluster, :disabled, projects: [project]) }
context 'when deployment is successful' do
let!(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
context 'when modsecurity is in blocking mode' do
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'when deployment is unsuccessful' do
let!(:deployment) { create(:deployment, :failed, environment: environment, project: project, cluster: cluster) }
context 'when modsecurity is in logging mode' do
let(:ingress_mode) { :modsecurity_logging }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_logging]).to eq(1)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'when deployment is successful' do
let!(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
context 'when modsecurity is disabled' do
let(:ingress_mode) { :modsecurity_disabled }
context 'when modsecurity is in blocking mode' do
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(1)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'when modsecurity is in logging mode' do
let(:ingress_mode) { :modsecurity_logging }
context 'when modsecurity is not installed' do
let(:ingress_mode) { :modsecurity_not_installed }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(1)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(1)
end
end
context 'when modsecurity is disabled' do
let(:ingress_mode) { :modsecurity_disabled }
context 'with multiple projects' do
let(:environment_2) { create(:environment) }
let(:project_2) { environment_2.project }
let(:cluster_2) { create(:cluster, environment_scope: environment_scope, projects: [project_2]) }
let!(:ingress_2) { create(:clusters_applications_ingress, :modsecurity_logging, cluster: cluster_2) }
let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster_2) }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(1)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
it 'gathers non-duplicated ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(1)
expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'when modsecurity is not installed' do
let(:ingress_mode) { :modsecurity_not_installed }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(1)
end
end
context 'with multiple deployments' do
let!(:deployment_2) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
context 'with multiple projects' do
let(:environment_2) { create(:environment) }
let(:project_2) { environment_2.project }
let(:cluster_2) { create(:cluster, environment_scope: environment_scope, projects: [project_2]) }
let!(:ingress_2) { create(:clusters_applications_ingress, :modsecurity_logging, cluster: cluster_2) }
let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster_2) }
it 'gathers non-duplicated ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(1)
expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
it 'gathers non-duplicated ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'with multiple deployments' do
let!(:deployment_2) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
context 'with multiple projects' do
let(:environment_2) { create(:environment) }
let(:project_2) { environment_2.project }
let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster) }
let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project, project_2]) }
it 'gathers non-duplicated ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'with multiple projects' do
let(:environment_2) { create(:environment) }
let(:project_2) { environment_2.project }
let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster) }
let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project, project_2]) }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(2)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(2)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
context 'with multiple environments' do
let!(:environment_2) { create(:environment, project: project) }
let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project, cluster: cluster) }
context 'with multiple environments' do
let!(:environment_2) { create(:environment, project: project) }
let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project, cluster: cluster) }
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(2)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
expect(subject[:ingress_modsecurity_blocking]).to eq(2)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
end
end
describe '#grafana_embed_usage_data' do
subject { described_class.grafana_embed_usage_data }
describe '#grafana_embed_usage_data' do
subject { described_class.grafana_embed_usage_data }
let(:project) { create(:project) }
let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" }
let(:project) { create(:project) }
let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" }
shared_examples "zero count" do
it "does not count the issue" do
expect(subject).to eq(0)
end
shared_examples "zero count" do
it "does not count the issue" do
expect(subject).to eq(0)
end
end
context 'with project grafana integration enabled' do
before do
create(:grafana_integration, project: project, enabled: true)
end
context 'with valid and invalid embeds' do
before do
# Valid
create(:issue, project: project, description: description_with_embed)
create(:issue, project: project, description: description_with_embed)
# In-Valid
create(:issue, project: project, description: description_with_unintegrated_embed)
create(:issue, project: project, description: description_with_non_grafana_inline_metric)
create(:issue, project: project, description: nil)
create(:issue, project: project, description: '')
create(:issue, project: project)
end
it 'counts only the issues with embeds' do
expect(subject).to eq(2)
end
end
context 'with project grafana integration enabled' do
before do
create(:grafana_integration, project: project, enabled: true)
end
context 'with project grafana integration disabled' do
context 'with valid and invalid embeds' do
before do
create(:grafana_integration, project: project, enabled: false)
# Valid
create(:issue, project: project, description: description_with_embed)
create(:issue, project: project, description: description_with_embed)
# In-Valid
create(:issue, project: project, description: description_with_unintegrated_embed)
create(:issue, project: project, description: description_with_non_grafana_inline_metric)
create(:issue, project: project, description: nil)
create(:issue, project: project, description: '')
create(:issue, project: project)
end
context 'with one issue having a grafana link in the description and one without' do
before do
create(:issue, project: project, description: description_with_embed)
create(:issue, project: project)
end
it_behaves_like('zero count')
it 'counts only the issues with embeds' do
expect(subject).to eq(2)
end
end
end
context 'with an un-integrated project' do
context 'with one issue having a grafana link in the description and one without' do
before do
create(:issue, project: project, description: description_with_embed)
create(:issue, project: project)
end
context 'with project grafana integration disabled' do
before do
create(:grafana_integration, project: project, enabled: false)
end
it_behaves_like('zero count')
context 'with one issue having a grafana link in the description and one without' do
before do
create(:issue, project: project, description: description_with_embed)
create(:issue, project: project)
end
it_behaves_like('zero count')
end
end
end
end
context 'when usage usage_ping_batch_counter is true' do
before do
stub_feature_flags(usage_ping_batch_counter: true)
end
it_behaves_like 'usage data execution'
end
context 'with an un-integrated project' do
context 'with one issue having a grafana link in the description and one without' do
before do
create(:issue, project: project, description: description_with_embed)
create(:issue, project: project)
end
context 'when usage usage_ping_batch_counter is false' do
before do
stub_feature_flags(usage_ping_batch_counter: false)
it_behaves_like('zero count')
end
end
end
it_behaves_like 'usage data execution'
end
describe '#merge_requests_usage_data' do
......
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