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

3 4
require 'spec_helper'

5 6
describe Gitlab::UsageData, :aggregate_failures do
  include UsageDataHelpers
7

8 9 10
  before do
    allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
  end
11 12 13 14 15

  shared_examples "usage data execution" do
    describe '#data' do
      let!(:ud) { build(:usage_data) }

16
      before do
17
        allow(Gitlab::GrafanaEmbedUsageData).to receive(:issue_count).and_return(2)
18
      end
19

20
      subject { described_class.data }
21

22 23 24
      it 'gathers usage data' do
        expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS)
      end
25

26 27
      it 'gathers usage counts' do
        count_data = subject[:counts]
28

29 30 31 32 33 34
        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
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
      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[: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[: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[:clusters_enabled]).to eq(4)
        expect(count_data[:project_clusters_enabled]).to eq(3)
        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)
        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)
      end
81

82 83 84
      it 'works when queries time out' do
        allow_any_instance_of(ActiveRecord::Relation)
          .to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
85

86
        expect { subject }.not_to raise_error
87
      end
88
    end
89

90 91
    describe '#usage_data_counters' do
      subject { described_class.usage_data_counters }
92

93
      it { is_expected.to all(respond_to :totals) }
A
Alex Kalderimis 已提交
94

95 96
      describe 'the results of calling #totals on all objects in the array' do
        subject { described_class.usage_data_counters.map(&:totals) }
A
Alex Kalderimis 已提交
97

98 99 100
        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
A
Alex Kalderimis 已提交
101

102 103
      it 'does not have any conflicts' do
        all_keys = subject.flat_map { |counter| counter.totals.keys }
A
Alex Kalderimis 已提交
104

105
        expect(all_keys.size).to eq all_keys.to_set.size
106
      end
107
    end
A
Alex Kalderimis 已提交
108

109 110 111 112 113 114 115 116 117 118 119 120 121
    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
    end

    context 'when not relying on database records' do
122 123 124
      describe '#features_usage_data_ce' do
        subject { described_class.features_usage_data_ce }

125
        it 'gathers feature usage data' do
126 127 128 129 130 131 132 133 134 135 136 137
          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?)
        end
      end
A
Alex Kalderimis 已提交
138

139 140 141
      describe '#components_usage_data' do
        subject { described_class.components_usage_data }

142
        it 'gathers components usage data' do
143 144 145 146 147 148 149 150 151 152 153
          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][:filesystems]).to be_an(Array)
          expect(subject[:gitaly][:filesystems].first).to be_a(String)
        end
      end
154

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
      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(''))

          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(''))

          expect { subject }.not_to raise_error
        end
      end

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
      describe '#ingress_modsecurity_usage' do
        subject { described_class.ingress_modsecurity_usage }

        it 'gathers variable data' do
          allow_any_instance_of(
            ::Clusters::Applications::IngressModsecurityUsageService
          ).to receive(:execute).and_return(
            {
              ingress_modsecurity_blocking: 1,
              ingress_modsecurity_disabled: 2
            }
          )

          expect(subject[:ingress_modsecurity_blocking]).to eq(1)
          expect(subject[:ingress_modsecurity_disabled]).to eq(2)
        end
      end
190

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

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

197 198
          expect(described_class.count(relation, batch: false)).to eq(1)
        end
199

200 201
        it 'returns the fallback value when counting fails' do
          allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
202

203 204 205
          expect(described_class.count(relation, fallback: 15, batch: false)).to eq(15)
        end
      end
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221

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

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

          expect(described_class.distinct_count(relation, batch: false)).to eq(1)
        end

        it 'returns the fallback value when counting fails' do
          allow(relation).to receive(:distinct_count_by).and_raise(ActiveRecord::StatementInvalid.new(''))

          expect(described_class.distinct_count(relation, fallback: 15, batch: false)).to eq(15)
        end
      end
222 223
    end
  end
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

  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 'when usage usage_ping_batch_counter is false' do
    before do
      stub_feature_flags(usage_ping_batch_counter: false)
    end

    it_behaves_like 'usage data execution'
  end
240
end