debian-mirror-gitlab/spec/lib/gitlab/experimentation_spec.rb

162 lines
4.3 KiB
Ruby
Raw Normal View History

2019-12-21 20:55:43 +05:30
# frozen_string_literal: true
require 'spec_helper'
2021-01-29 00:20:46 +05:30
2021-02-22 17:27:13 +05:30
RSpec.describe Gitlab::Experimentation do
2021-03-11 19:13:27 +05:30
using RSpec::Parameterized::TableSyntax
2019-12-26 22:10:19 +05:30
before do
stub_const('Gitlab::Experimentation::EXPERIMENTS', {
test_experiment: {
tracking_category: 'Team'
2021-03-11 19:13:27 +05:30
},
tabular_experiment: {
tracking_category: 'Team',
rollout_strategy: rollout_strategy
2019-12-26 22:10:19 +05:30
}
})
2019-12-21 20:55:43 +05:30
2021-03-08 18:12:59 +05:30
skip_feature_flags_yaml_validation
skip_default_enabled_yaml_check
2020-06-23 00:09:42 +05:30
Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
2021-02-22 17:27:13 +05:30
allow(Gitlab).to receive(:com?).and_return(true)
2019-12-21 20:55:43 +05:30
end
2020-05-24 23:13:21 +05:30
let(:enabled_percentage) { 10 }
2021-03-11 19:13:27 +05:30
let(:rollout_strategy) { nil }
2019-12-26 22:10:19 +05:30
2021-02-22 17:27:13 +05:30
describe '.get_experiment' do
subject { described_class.get_experiment(:test_experiment) }
2019-12-21 20:55:43 +05:30
2021-02-22 17:27:13 +05:30
context 'returns experiment' do
it { is_expected.to be_instance_of(Gitlab::Experimentation::Experiment) }
end
context 'experiment is not defined' do
subject { described_class.get_experiment(:missing_experiment) }
it { is_expected.to be_nil }
end
end
describe '.active?' do
subject { described_class.active?(:test_experiment) }
context 'feature toggle is enabled' do
it { is_expected.to eq(true) }
2019-12-21 20:55:43 +05:30
end
describe 'experiment is not defined' do
it 'returns false' do
2021-02-22 17:27:13 +05:30
expect(described_class.active?(:missing_experiment)).to eq(false)
2019-12-21 20:55:43 +05:30
end
end
2020-05-24 23:13:21 +05:30
describe 'experiment is disabled' do
let(:enabled_percentage) { 0 }
2019-12-21 20:55:43 +05:30
2021-02-22 17:27:13 +05:30
it { is_expected.to eq(false) }
2019-12-21 20:55:43 +05:30
end
2021-02-22 17:27:13 +05:30
end
2019-12-21 20:55:43 +05:30
2021-02-22 17:27:13 +05:30
describe '.in_experiment_group?' do
2021-11-11 11:23:49 +05:30
let(:enabled_percentage) { 50 }
let(:experiment_subject) { 'z' } # Zlib.crc32('test_experimentz') % 100 = 33
2021-01-29 00:20:46 +05:30
2021-11-11 11:23:49 +05:30
subject { described_class.in_experiment_group?(:test_experiment, subject: experiment_subject) }
2021-01-29 00:20:46 +05:30
2021-11-11 11:23:49 +05:30
context 'when experiment is active' do
context 'when subject is part of the experiment' do
it { is_expected.to eq(true) }
end
2021-02-22 17:27:13 +05:30
2021-11-11 11:23:49 +05:30
context 'when subject is not part of the experiment' do
let(:experiment_subject) { 'a' } # Zlib.crc32('test_experimenta') % 100 = 61
2021-02-22 17:27:13 +05:30
2021-11-11 11:23:49 +05:30
it { is_expected.to eq(false) }
end
2021-02-22 17:27:13 +05:30
2021-11-11 11:23:49 +05:30
context 'when subject has a global_id' do
let(:experiment_subject) { double(:subject, to_global_id: 'z') }
2019-12-21 20:55:43 +05:30
2021-11-11 11:23:49 +05:30
it { is_expected.to eq(true) }
end
2019-12-21 20:55:43 +05:30
2021-11-11 11:23:49 +05:30
context 'when subject is nil' do
let(:experiment_subject) { nil }
2019-12-26 22:10:19 +05:30
2021-11-11 11:23:49 +05:30
it { is_expected.to eq(false) }
2019-12-21 20:55:43 +05:30
end
2021-11-11 11:23:49 +05:30
context 'when subject is an empty string' do
let(:experiment_subject) { '' }
2019-12-21 20:55:43 +05:30
2021-02-22 17:27:13 +05:30
it { is_expected.to eq(false) }
2019-12-21 20:55:43 +05:30
end
2021-02-22 17:27:13 +05:30
end
2019-12-21 20:55:43 +05:30
2021-11-11 11:23:49 +05:30
context 'when experiment is not active' do
before do
allow(described_class).to receive(:active?).and_return(false)
2021-02-22 17:27:13 +05:30
end
2021-01-03 14:25:43 +05:30
2021-11-11 11:23:49 +05:30
it { is_expected.to eq(false) }
2021-01-03 14:25:43 +05:30
end
end
2021-03-11 19:13:27 +05:30
describe '.log_invalid_rollout' do
subject { described_class.log_invalid_rollout(:test_experiment, 1) }
before do
allow(described_class).to receive(:valid_subject_for_rollout_strategy?).and_return(valid)
end
context 'subject is not valid for experiment' do
let(:valid) { false }
it 'logs a warning message' do
expect_next_instance_of(Gitlab::ExperimentationLogger) do |logger|
expect(logger)
.to receive(:warn)
.with(
message: 'Subject must conform to the rollout strategy',
experiment_key: :test_experiment,
subject: 'Integer',
rollout_strategy: :cookie
)
end
subject
end
end
context 'subject is valid for experiment' do
let(:valid) { true }
it 'does not log a warning message' do
expect(Gitlab::ExperimentationLogger).not_to receive(:build)
subject
end
end
end
describe '.valid_subject_for_rollout_strategy?' do
subject { described_class.valid_subject_for_rollout_strategy?(:tabular_experiment, experiment_subject) }
where(:rollout_strategy, :experiment_subject, :result) do
:cookie | nil | true
nil | nil | true
:cookie | 'string' | true
nil | User.new | false
:user | User.new | true
:group | User.new | false
:group | Group.new | true
end
with_them do
it { is_expected.to be(result) }
end
end
2019-12-21 20:55:43 +05:30
end