diff options
Diffstat (limited to 'spec/lib/gitlab/experimentation_spec.rb')
-rw-r--r-- | spec/lib/gitlab/experimentation_spec.rb | 152 |
1 files changed, 86 insertions, 66 deletions
diff --git a/spec/lib/gitlab/experimentation_spec.rb b/spec/lib/gitlab/experimentation_spec.rb index ebf98a0151f..a68c050d829 100644 --- a/spec/lib/gitlab/experimentation_spec.rb +++ b/spec/lib/gitlab/experimentation_spec.rb @@ -13,11 +13,8 @@ RSpec.describe Gitlab::Experimentation::EXPERIMENTS do :invite_members_version_a, :invite_members_version_b, :invite_members_empty_group_version_a, - :new_create_project_ui, :contact_sales_btn_in_app, :customize_homepage, - :invite_email, - :invitation_reminders, :group_only_trials, :default_to_issues_board ] @@ -29,127 +26,150 @@ RSpec.describe Gitlab::Experimentation::EXPERIMENTS do end end -RSpec.describe Gitlab::Experimentation, :snowplow do +RSpec.describe Gitlab::Experimentation do before do stub_const('Gitlab::Experimentation::EXPERIMENTS', { backwards_compatible_test_experiment: { - environment: environment, tracking_category: 'Team', use_backwards_compatible_subject_index: true }, test_experiment: { - environment: environment, tracking_category: 'Team' } }) Feature.enable_percentage_of_time(:backwards_compatible_test_experiment_experiment_percentage, enabled_percentage) Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage) + allow(Gitlab).to receive(:com?).and_return(true) end - let(:environment) { Rails.env.test? } let(:enabled_percentage) { 10 } - describe '.enabled?' do - subject { described_class.enabled?(:test_experiment) } + describe '.get_experiment' do + subject { described_class.get_experiment(:test_experiment) } - context 'feature toggle is enabled, we are on the right environment and we are selected' do - it { is_expected.to be_truthy } + 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) } end describe 'experiment is not defined' do it 'returns false' do - expect(described_class.enabled?(:missing_experiment)).to be_falsey + expect(described_class.active?(:missing_experiment)).to eq(false) end end describe 'experiment is disabled' do let(:enabled_percentage) { 0 } - it { is_expected.to be_falsey } + it { is_expected.to eq(false) } end + end - describe 'we are on the wrong environment' do - let(:environment) { ::Gitlab.com? } + describe '.in_experiment_group?' do + context 'with new index calculation' do + let(:enabled_percentage) { 50 } + let(:experiment_subject) { 'z' } # Zlib.crc32('test_experimentz') % 100 = 33 - it { is_expected.to be_falsey } + subject { described_class.in_experiment_group?(:test_experiment, subject: experiment_subject) } - it 'ensures the typically less expensive environment is checked before the more expensive call to database for Feature' do - expect_next_instance_of(described_class::Experiment) do |experiment| - expect(experiment).not_to receive(:enabled?) + context 'when experiment is active' do + context 'when subject is part of the experiment' do + it { is_expected.to eq(true) } end - subject - end - end - end + context 'when subject is not part of the experiment' do + let(:experiment_subject) { 'a' } # Zlib.crc32('test_experimenta') % 100 = 61 + + it { is_expected.to eq(false) } + end + + context 'when subject has a global_id' do + let(:experiment_subject) { double(:subject, to_global_id: 'z') } + + it { is_expected.to eq(true) } + end + + context 'when subject is nil' do + let(:experiment_subject) { nil } - describe '.enabled_for_value?' do - subject { described_class.enabled_for_value?(:test_experiment, experimentation_subject_index) } + it { is_expected.to eq(false) } + end - let(:experimentation_subject_index) { 9 } + context 'when subject is an empty string' do + let(:experiment_subject) { '' } - context 'experiment is disabled' do - before do - allow(described_class).to receive(:enabled?).and_return(false) + it { is_expected.to eq(false) } + end end - it { is_expected.to be_falsey } - end + context 'when experiment is not active' do + before do + allow(described_class).to receive(:active?).and_return(false) + end - context 'experiment is enabled' do - before do - allow(described_class).to receive(:enabled?).and_return(true) + it { is_expected.to eq(false) } end + end - it { is_expected.to be_truthy } + context 'with backwards compatible index calculation' do + let(:experiment_subject) { 'abcd' } # Digest::SHA1.hexdigest('abcd').hex % 100 = 7 - describe 'experimentation_subject_index' do - context 'experimentation_subject_index is not set' do - let(:experimentation_subject_index) { nil } + subject { described_class.in_experiment_group?(:backwards_compatible_test_experiment, subject: experiment_subject) } - it { is_expected.to be_falsey } + context 'when experiment is active' do + before do + allow(described_class).to receive(:active?).and_return(true) end - context 'experimentation_subject_index is an empty string' do - let(:experimentation_subject_index) { '' } - - it { is_expected.to be_falsey } + context 'when subject is part of the experiment' do + it { is_expected.to eq(true) } end - context 'experimentation_subject_index outside enabled ratio' do - let(:experimentation_subject_index) { 11 } + context 'when subject is not part of the experiment' do + let(:experiment_subject) { 'abc' } # Digest::SHA1.hexdigest('abc').hex % 100 = 17 - it { is_expected.to be_falsey } + it { is_expected.to eq(false) } end - end - end - end - describe '.enabled_for_attribute?' do - subject { described_class.enabled_for_attribute?(:test_experiment, attribute) } + context 'when subject has a global_id' do + let(:experiment_subject) { double(:subject, to_global_id: 'abcd') } - let(:attribute) { 'abcd' } # Digest::SHA1.hexdigest('abcd').hex % 100 = 7 + it { is_expected.to eq(true) } + end - context 'experiment is disabled' do - before do - allow(described_class).to receive(:enabled?).and_return(false) - end + context 'when subject is nil' do + let(:experiment_subject) { nil } - it { is_expected.to be false } - end + it { is_expected.to eq(false) } + end - context 'experiment is enabled' do - before do - allow(described_class).to receive(:enabled?).and_return(true) - end + context 'when subject is an empty string' do + let(:experiment_subject) { '' } - it { is_expected.to be true } + it { is_expected.to eq(false) } + end + end - context 'outside enabled ratio' do - let(:attribute) { 'abc' } # Digest::SHA1.hexdigest('abc').hex % 100 = 17 + context 'when experiment is not active' do + before do + allow(described_class).to receive(:active?).and_return(false) + end - it { is_expected.to be false } + it { is_expected.to eq(false) } end end end |