Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb')
-rw-r--r--spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb228
1 files changed, 69 insertions, 159 deletions
diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
index b8eddc0ca7f..b4894ec049f 100644
--- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
@@ -27,6 +27,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'deploy_token_packages',
'user_packages',
'compliance',
+ 'ecosystem',
'analytics',
'ide_edit',
'search',
@@ -39,12 +40,16 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'snippets',
'code_review',
'terraform',
- 'ci_templates'
+ 'ci_templates',
+ 'quickactions',
+ 'pipeline_authoring'
)
end
end
describe 'known_events' do
+ let(:feature) { 'test_hll_redis_counter_ff_check' }
+
let(:weekly_event) { 'g_analytics_contribution' }
let(:daily_event) { 'g_analytics_search' }
let(:analytics_slot_event) { 'g_analytics_contribution' }
@@ -64,7 +69,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
let(:known_events) do
[
- { name: weekly_event, redis_slot: "analytics", category: analytics_category, expiry: 84, aggregation: "weekly" },
+ { name: weekly_event, redis_slot: "analytics", category: analytics_category, expiry: 84, aggregation: "weekly", feature_flag: feature },
{ name: daily_event, redis_slot: "analytics", category: analytics_category, expiry: 84, aggregation: "daily" },
{ name: category_productivity_event, redis_slot: "analytics", category: productivity_category, aggregation: "weekly" },
{ name: compliance_slot_event, redis_slot: "compliance", category: compliance_category, aggregation: "weekly" },
@@ -75,6 +80,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
end
before do
+ skip_feature_flags_yaml_validation
+ skip_default_enabled_yaml_check
allow(described_class).to receive(:known_events).and_return(known_events)
end
@@ -85,6 +92,32 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
end
describe '.track_event' do
+ context 'with feature flag set' do
+ it 'tracks the event when feature enabled' do
+ stub_feature_flags(feature => true)
+
+ expect(Gitlab::Redis::HLL).to receive(:add)
+
+ described_class.track_event(weekly_event, values: 1)
+ end
+
+ it 'does not track the event with feature flag disabled' do
+ stub_feature_flags(feature => false)
+
+ expect(Gitlab::Redis::HLL).not_to receive(:add)
+
+ described_class.track_event(weekly_event, values: 1)
+ end
+ end
+
+ context 'with no feature flag set' do
+ it 'tracks the event' do
+ expect(Gitlab::Redis::HLL).to receive(:add)
+
+ described_class.track_event(daily_event, values: 1)
+ end
+ end
+
context 'when usage_ping is disabled' do
it 'does not track the event' do
stub_application_setting(usage_ping_enabled: false)
@@ -425,182 +458,59 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
end
end
- context 'aggregated_metrics_data' do
+ describe '.calculate_events_union' do
+ let(:time_range) { { start_date: 7.days.ago, end_date: DateTime.current } }
let(:known_events) do
[
{ name: 'event1_slot', redis_slot: "slot", category: 'category1', aggregation: "weekly" },
{ name: 'event2_slot', redis_slot: "slot", category: 'category2', aggregation: "weekly" },
{ name: 'event3_slot', redis_slot: "slot", category: 'category3', aggregation: "weekly" },
- { name: 'event5_slot', redis_slot: "slot", category: 'category4', aggregation: "weekly" },
+ { name: 'event5_slot', redis_slot: "slot", category: 'category4', aggregation: "daily" },
{ name: 'event4', category: 'category2', aggregation: "weekly" }
].map(&:with_indifferent_access)
end
before do
allow(described_class).to receive(:known_events).and_return(known_events)
- end
-
- shared_examples 'aggregated_metrics_data' do
- context 'no aggregated metrics is defined' do
- it 'returns empty hash' do
- allow(described_class).to receive(:aggregated_metrics).and_return([])
-
- expect(aggregated_metrics_data).to eq({})
- end
- end
-
- context 'there are aggregated metrics defined' do
- before do
- allow(described_class).to receive(:aggregated_metrics).and_return(aggregated_metrics)
- end
-
- context 'with AND operator' do
- let(:aggregated_metrics) do
- [
- { name: 'gmau_1', events: %w[event1_slot event2_slot], operator: "AND" },
- { name: 'gmau_2', events: %w[event1_slot event2_slot event3_slot], operator: "AND" },
- { name: 'gmau_3', events: %w[event1_slot event2_slot event3_slot event5_slot], operator: "AND" },
- { name: 'gmau_4', events: %w[event4], operator: "AND" }
- ].map(&:with_indifferent_access)
- end
-
- it 'returns the number of unique events for all known events' do
- results = {
- 'gmau_1' => 3,
- 'gmau_2' => 2,
- 'gmau_3' => 1,
- 'gmau_4' => 3
- }
-
- expect(aggregated_metrics_data).to eq(results)
- end
- end
-
- context 'with OR operator' do
- let(:aggregated_metrics) do
- [
- { name: 'gmau_1', events: %w[event3_slot event5_slot], operator: "OR" },
- { name: 'gmau_2', events: %w[event1_slot event2_slot event3_slot event5_slot], operator: "OR" },
- { name: 'gmau_3', events: %w[event4], operator: "OR" }
- ].map(&:with_indifferent_access)
- end
- it 'returns the number of unique events for all known events' do
- results = {
- 'gmau_1' => 2,
- 'gmau_2' => 3,
- 'gmau_3' => 3
- }
-
- expect(aggregated_metrics_data).to eq(results)
- end
- end
-
- context 'hidden behind feature flag' do
- let(:enabled_feature_flag) { 'test_ff_enabled' }
- let(:disabled_feature_flag) { 'test_ff_disabled' }
- let(:aggregated_metrics) do
- [
- # represents stable aggregated metrics that has been fully released
- { name: 'gmau_without_ff', events: %w[event3_slot event5_slot], operator: "OR" },
- # represents new aggregated metric that is under performance testing on gitlab.com
- { name: 'gmau_enabled', events: %w[event4], operator: "AND", feature_flag: enabled_feature_flag },
- # represents aggregated metric that is under development and shouldn't be yet collected even on gitlab.com
- { name: 'gmau_disabled', events: %w[event4], operator: "AND", feature_flag: disabled_feature_flag }
- ].map(&:with_indifferent_access)
- end
-
- it 'returns the number of unique events for all known events' do
- skip_feature_flags_yaml_validation
- stub_feature_flags(enabled_feature_flag => true, disabled_feature_flag => false)
+ described_class.track_event('event1_slot', values: entity1, time: 2.days.ago)
+ described_class.track_event('event1_slot', values: entity2, time: 2.days.ago)
+ described_class.track_event('event1_slot', values: entity3, time: 2.days.ago)
+ described_class.track_event('event2_slot', values: entity1, time: 2.days.ago)
+ described_class.track_event('event2_slot', values: entity2, time: 3.days.ago)
+ described_class.track_event('event2_slot', values: entity3, time: 3.days.ago)
+ described_class.track_event('event3_slot', values: entity1, time: 3.days.ago)
+ described_class.track_event('event3_slot', values: entity2, time: 3.days.ago)
+ described_class.track_event('event5_slot', values: entity2, time: 3.days.ago)
+
+ # events out of time scope
+ described_class.track_event('event2_slot', values: entity4, time: 8.days.ago)
- expect(aggregated_metrics_data).to eq('gmau_without_ff' => 2, 'gmau_enabled' => 3)
- end
- end
- end
+ # events in different slots
+ described_class.track_event('event4', values: entity1, time: 2.days.ago)
+ described_class.track_event('event4', values: entity2, time: 2.days.ago)
end
- describe '.aggregated_metrics_weekly_data' do
- subject(:aggregated_metrics_data) { described_class.aggregated_metrics_weekly_data }
-
- before do
- described_class.track_event('event1_slot', values: entity1, time: 2.days.ago)
- described_class.track_event('event1_slot', values: entity2, time: 2.days.ago)
- described_class.track_event('event1_slot', values: entity3, time: 2.days.ago)
- described_class.track_event('event2_slot', values: entity1, time: 2.days.ago)
- described_class.track_event('event2_slot', values: entity2, time: 3.days.ago)
- described_class.track_event('event2_slot', values: entity3, time: 3.days.ago)
- described_class.track_event('event3_slot', values: entity1, time: 3.days.ago)
- described_class.track_event('event3_slot', values: entity2, time: 3.days.ago)
- described_class.track_event('event5_slot', values: entity2, time: 3.days.ago)
-
- # events out of time scope
- described_class.track_event('event2_slot', values: entity3, time: 8.days.ago)
-
- # events in different slots
- described_class.track_event('event4', values: entity1, time: 2.days.ago)
- described_class.track_event('event4', values: entity2, time: 2.days.ago)
- described_class.track_event('event4', values: entity4, time: 2.days.ago)
- end
-
- it_behaves_like 'aggregated_metrics_data'
+ it 'calculates union of given events', :aggregate_failure do
+ expect(described_class.calculate_events_union(**time_range.merge(event_names: %w[event4]))).to eq 2
+ expect(described_class.calculate_events_union(**time_range.merge(event_names: %w[event1_slot event2_slot event3_slot]))).to eq 3
end
- describe '.aggregated_metrics_monthly_data' do
- subject(:aggregated_metrics_data) { described_class.aggregated_metrics_monthly_data }
-
- it_behaves_like 'aggregated_metrics_data' do
- before do
- described_class.track_event('event1_slot', values: entity1, time: 2.days.ago)
- described_class.track_event('event1_slot', values: entity2, time: 2.days.ago)
- described_class.track_event('event1_slot', values: entity3, time: 2.days.ago)
- described_class.track_event('event2_slot', values: entity1, time: 2.days.ago)
- described_class.track_event('event2_slot', values: entity2, time: 3.days.ago)
- described_class.track_event('event2_slot', values: entity3, time: 3.days.ago)
- described_class.track_event('event3_slot', values: entity1, time: 3.days.ago)
- described_class.track_event('event3_slot', values: entity2, time: 10.days.ago)
- described_class.track_event('event5_slot', values: entity2, time: 4.weeks.ago.advance(days: 1))
-
- # events out of time scope
- described_class.track_event('event5_slot', values: entity1, time: 4.weeks.ago.advance(days: -1))
-
- # events in different slots
- described_class.track_event('event4', values: entity1, time: 2.days.ago)
- described_class.track_event('event4', values: entity2, time: 2.days.ago)
- described_class.track_event('event4', values: entity4, time: 2.days.ago)
- end
- end
-
- context 'Redis calls' do
- let(:aggregated_metrics) do
- [
- { name: 'gmau_3', events: %w[event1_slot event2_slot event3_slot event5_slot], operator: "AND" }
- ].map(&:with_indifferent_access)
- end
-
- let(:known_events) do
- [
- { name: 'event1_slot', redis_slot: "slot", category: 'category1', aggregation: "weekly" },
- { name: 'event2_slot', redis_slot: "slot", category: 'category2', aggregation: "weekly" },
- { name: 'event3_slot', redis_slot: "slot", category: 'category3', aggregation: "weekly" },
- { name: 'event5_slot', redis_slot: "slot", category: 'category4', aggregation: "weekly" }
- ].map(&:with_indifferent_access)
- end
-
- it 'caches intermediate operations' do
- allow(described_class).to receive(:known_events).and_return(known_events)
- allow(described_class).to receive(:aggregated_metrics).and_return(aggregated_metrics)
+ it 'validates and raise exception if events has mismatched slot or aggregation', :aggregate_failure do
+ expect { described_class.calculate_events_union(**time_range.merge(event_names: %w[event1_slot event4])) }.to raise_error described_class::SlotMismatch
+ expect { described_class.calculate_events_union(**time_range.merge(event_names: %w[event5_slot event3_slot])) }.to raise_error described_class::AggregationMismatch
+ end
+ end
- 4.downto(1) do |subset_size|
- known_events.combination(subset_size).each do |events|
- keys = described_class.send(:weekly_redis_keys, events: events, start_date: 4.weeks.ago.to_date, end_date: Date.current)
- expect(Gitlab::Redis::HLL).to receive(:count).with(keys: keys).once.and_return(0)
- end
- end
+ describe '.weekly_time_range' do
+ it 'return hash with weekly time range boundaries' do
+ expect(described_class.weekly_time_range).to eq(start_date: 7.days.ago.to_date, end_date: Date.current)
+ end
+ end
- subject
- end
- end
+ describe '.monthly_time_range' do
+ it 'return hash with monthly time range boundaries' do
+ expect(described_class.monthly_time_range).to eq(start_date: 4.weeks.ago.to_date, end_date: Date.current)
end
end
end