usage_data_spec.rb 11.3 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5
require 'spec_helper'

describe Gitlab::UsageData do
6
  let(:projects) { create_list(:project, 4) }
7
  let!(:board) { create(:board, project: projects[0]) }
8 9

  describe '#data' do
10 11
    before do
      create(:jira_service, project: projects[0])
12
      create(:jira_service, :without_properties_callback, project: projects[1])
13
      create(:jira_service, :jira_cloud_service, project: projects[2])
14 15
      create(:jira_service, :without_properties_callback, project: projects[3],
             properties: { url: 'https://mysite.atlassian.net' })
16 17 18 19
      create(:prometheus_service, project: projects[1])
      create(:service, project: projects[0], type: 'SlackSlashCommandsService', active: true)
      create(:service, project: projects[1], type: 'SlackService', active: true)
      create(:service, project: projects[2], type: 'SlackService', active: true)
L
Logan King 已提交
20 21
      create(:project_error_tracking_setting, project: projects[0])
      create(:project_error_tracking_setting, project: projects[1], enabled: false)
22 23 24 25

      gcp_cluster = create(:cluster, :provided_by_gcp)
      create(:cluster, :provided_by_user)
      create(:cluster, :provided_by_user, :disabled)
26 27 28
      create(:cluster, :group)
      create(:cluster, :group, :disabled)
      create(:cluster, :group, :disabled)
29 30
      create(:clusters_applications_helm, :installed, cluster: gcp_cluster)
      create(:clusters_applications_ingress, :installed, cluster: gcp_cluster)
J
João Cunha 已提交
31
      create(:clusters_applications_cert_manager, :installed, cluster: gcp_cluster)
32 33
      create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster)
      create(:clusters_applications_runner, :installed, cluster: gcp_cluster)
34
      create(:clusters_applications_knative, :installed, cluster: gcp_cluster)
35
      create(:clusters_applications_elastic_stack, :installed, cluster: gcp_cluster)
36 37

      ProjectFeature.first.update_attribute('repository_access_level', 0)
38 39
    end

40
    subject { described_class.data }
41

42
    it 'gathers usage data', :aggregate_failures do
J
James Lopez 已提交
43
      expect(subject.keys).to include(*%i(
44 45 46
        active_user_count
        counts
        recorded_at
S
Sean McGivern 已提交
47
        edition
48
        version
49
        installation_type
50
        uuid
S
Sean McGivern 已提交
51
        hostname
52 53 54 55 56 57 58
        mattermost_enabled
        signup_enabled
        ldap_enabled
        gravatar_enabled
        omniauth_enabled
        reply_by_email_enabled
        container_registry_enabled
59
        dependency_proxy_enabled
60
        gitlab_shared_runners_enabled
61 62
        gitlab_pages
        git
63
        gitaly
64
        database
65
        avg_cycle_analytics
R
Ryan Cobb 已提交
66 67
        influxdb_metrics_enabled
        prometheus_metrics_enabled
68
      ))
69 70
    end

71
    it 'gathers usage counts' do
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
      smau_keys = %i(
        snippet_create
        snippet_update
        snippet_comment
        merge_request_comment
        merge_request_create
        commit_comment
        wiki_pages_create
        wiki_pages_update
        wiki_pages_delete
        web_ide_views
        web_ide_commits
        web_ide_merge_requests
        navbar_searches
        cycle_analytics_views
        productivity_analytics_views
        source_code_pushes
      )

91
      expected_keys = %i(
92
        assignee_lists
93 94
        boards
        ci_builds
95 96
        ci_internal_pipelines
        ci_external_pipelines
97 98
        ci_pipeline_config_auto_devops
        ci_pipeline_config_repository
99 100
        ci_runners
        ci_triggers
101
        ci_pipeline_schedules
102 103
        auto_devops_enabled
        auto_devops_disabled
104 105
        deploy_keys
        deployments
106 107
        successful_deployments
        failed_deployments
108
        environments
109 110
        clusters
        clusters_enabled
111 112
        project_clusters_enabled
        group_clusters_enabled
113
        clusters_disabled
114 115
        project_clusters_disabled
        group_clusters_disabled
116 117 118 119
        clusters_platforms_gke
        clusters_platforms_user
        clusters_applications_helm
        clusters_applications_ingress
A
Amit Rathi 已提交
120
        clusters_applications_cert_managers
121 122
        clusters_applications_prometheus
        clusters_applications_runner
123
        clusters_applications_knative
124
        clusters_applications_elastic_stack
125
        in_review_folder
126 127 128
        groups
        issues
        keys
129
        label_lists
130 131 132
        labels
        lfs_objects
        merge_requests
133
        milestone_lists
134 135
        milestones
        notes
136
        pool_repositories
137
        projects
138
        projects_imported_from_github
139
        projects_jira_active
140 141
        projects_jira_server_active
        projects_jira_cloud_active
142 143
        projects_slack_notifications_active
        projects_slack_slash_active
144
        projects_prometheus_active
145
        projects_with_repositories_enabled
L
Logan King 已提交
146
        projects_with_error_tracking_enabled
147 148 149
        pages_domains
        protected_branches
        releases
150
        remote_mirrors
151
        snippets
152
        suggestions
153
        todos
R
Robert Speicher 已提交
154
        uploads
155
        web_hooks
156
      ).push(*smau_keys)
157 158 159 160

      count_data = subject[:counts]

      expect(count_data[:boards]).to eq(1)
161
      expect(count_data[:projects]).to eq(4)
162
      expect(count_data.values_at(*smau_keys)).to all(be_an(Integer))
163 164
      expect(count_data.keys).to include(*expected_keys)
      expect(expected_keys - count_data.keys).to be_empty
165
    end
166

167
    it 'gathers projects data correctly', :aggregate_failures do
168 169
      count_data = subject[:counts]

170
      expect(count_data[:projects]).to eq(4)
171
      expect(count_data[:projects_prometheus_active]).to eq(1)
172
      expect(count_data[:projects_jira_active]).to eq(4)
173
      expect(count_data[:projects_jira_server_active]).to eq(2)
174
      expect(count_data[:projects_jira_cloud_active]).to eq(2)
175 176
      expect(count_data[:projects_slack_notifications_active]).to eq(2)
      expect(count_data[:projects_slack_slash_active]).to eq(1)
177
      expect(count_data[:projects_with_repositories_enabled]).to eq(3)
L
Logan King 已提交
178
      expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
179

180 181 182 183 184 185 186
      expect(count_data[:clusters_enabled]).to eq(7)
      expect(count_data[:project_clusters_enabled]).to eq(6)
      expect(count_data[:group_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(2)
      expect(count_data[:group_clusters_enabled]).to eq(1)
187 188 189 190
      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)
A
Amit Rathi 已提交
191
      expect(count_data[:clusters_applications_cert_managers]).to eq(1)
192 193
      expect(count_data[:clusters_applications_prometheus]).to eq(1)
      expect(count_data[:clusters_applications_runner]).to eq(1)
194
      expect(count_data[:clusters_applications_knative]).to eq(1)
195
      expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
196
    end
197 198 199 200 201 202 203

    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
204 205
  end

A
Alex Kalderimis 已提交
206 207 208 209 210 211 212 213
  describe '#usage_data_counters' do
    subject { described_class.usage_data_counters }

    it { is_expected.to all(respond_to :totals) }

    describe 'the results of calling #totals on all objects in the array' do
      subject { described_class.usage_data_counters.map(&:totals) }

214 215
      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))) }
A
Alex Kalderimis 已提交
216 217 218 219 220 221 222 223 224
    end

    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
  end

225 226 227
  describe '#features_usage_data_ce' do
    subject { described_class.features_usage_data_ce }

228
    it 'gathers feature usage data', :aggregate_failures do
229 230 231 232
      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?)
233
      expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?)
234 235
      expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?)
      expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled)
236
      expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled)
237
      expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled)
238 239 240 241 242 243
    end
  end

  describe '#components_usage_data' do
    subject { described_class.components_usage_data }

244
    it 'gathers components usage data', :aggregate_failures do
245 246 247 248 249
      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)
250 251 252 253
      expect(subject[:gitaly][:version]).to be_present
      expect(subject[:gitaly][:servers]).to be >= 1
      expect(subject[:gitaly][:filesystems]).to be_an(Array)
      expect(subject[:gitaly][:filesystems].first).to be_a(String)
254 255 256
    end
  end

257
  describe '#license_usage_data' do
258
    subject { described_class.license_usage_data }
259

260
    it 'gathers license data', :aggregate_failures do
261
      expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
262
      expect(subject[:version]).to eq(Gitlab::VERSION)
263
      expect(subject[:installation_type]).to eq('gitlab-development-kit')
264 265 266 267
      expect(subject[:active_user_count]).to eq(User.active.count)
      expect(subject[:recorded_at]).to be_a(Time)
    end
  end
268 269 270 271 272 273 274 275 276 277

  describe '#count' do
    let(:relation) { double(:relation) }

    it 'returns the count when counting succeeds' do
      allow(relation).to receive(:count).and_return(1)

      expect(described_class.count(relation)).to eq(1)
    end

278 279 280 281 282 283
    it 'returns the count for count_by when provided' do
      allow(relation).to receive(:count).with(:creator_id).and_return(2)

      expect(described_class.count(relation, count_by: :creator_id)).to eq(2)
    end

284 285 286 287 288 289
    it 'returns the fallback value when counting fails' do
      allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))

      expect(described_class.count(relation, fallback: 15)).to eq(15)
    end
  end
290 291

  describe '#approximate_counts' do
292
    it 'gets approximate counts for selected models', :aggregate_failures do
293 294 295
      create(:label)

      expect(Gitlab::Database::Count).to receive(:approximate_counts)
296
                                           .with(described_class::APPROXIMATE_COUNT_MODELS).once.and_call_original
297 298 299 300 301 302 303

      counts = described_class.approximate_counts.values

      expect(counts.count).to eq(described_class::APPROXIMATE_COUNT_MODELS.count)
      expect(counts.any? { |count| count < 0 }).to be_falsey
    end

304
    it 'returns default values if counts can not be retrieved', :aggregate_failures do
305 306 307 308
      described_class::APPROXIMATE_COUNT_MODELS.map do |model|
        model.name.underscore.pluralize.to_sym
      end

309
      expect(Gitlab::Database::Count).to receive(:approximate_counts).and_return({})
310 311 312
      expect(described_class.approximate_counts.values.uniq).to eq([-1])
    end
  end
313
end