Commit e690390d authored by Imre Farkas's avatar Imre Farkas

Merge branch 'stub-ff-earlier' into 'master'

Stub feature flags earlier

See merge request gitlab-org/gitlab!38659
parents f6e53638 39264445
...@@ -17,9 +17,9 @@ RSpec.describe Groups::SharedProjectsController do ...@@ -17,9 +17,9 @@ RSpec.describe Groups::SharedProjectsController do
).execute(group) ).execute(group)
end end
let_it_be(:group) { create(:group) } let!(:group) { create(:group) }
let_it_be(:user) { create(:user) } let!(:user) { create(:user) }
let_it_be(:shared_project) do let!(:shared_project) do
shared_project = create(:project, namespace: user.namespace) shared_project = create(:project, namespace: user.namespace)
share_project(shared_project) share_project(shared_project)
......
...@@ -107,7 +107,6 @@ RSpec.configure do |config| ...@@ -107,7 +107,6 @@ RSpec.configure do |config|
config.include FixtureHelpers config.include FixtureHelpers
config.include NonExistingRecordsHelpers config.include NonExistingRecordsHelpers
config.include GitlabRoutingHelper config.include GitlabRoutingHelper
config.include StubFeatureFlags
config.include StubExperiments config.include StubExperiments
config.include StubGitlabCalls config.include StubGitlabCalls
config.include StubGitlabData config.include StubGitlabData
...@@ -140,6 +139,8 @@ RSpec.configure do |config| ...@@ -140,6 +139,8 @@ RSpec.configure do |config|
config.include SidekiqMiddleware config.include SidekiqMiddleware
config.include StubActionCableConnection, type: :channel config.include StubActionCableConnection, type: :channel
include StubFeatureFlags
if ENV['CI'] || ENV['RETRIES'] if ENV['CI'] || ENV['RETRIES']
# This includes the first try, i.e. tests will be run 4 times before failing. # This includes the first try, i.e. tests will be run 4 times before failing.
config.default_retry_count = ENV.fetch('RETRIES', 3).to_i + 1 config.default_retry_count = ENV.fetch('RETRIES', 3).to_i + 1
...@@ -158,6 +159,10 @@ RSpec.configure do |config| ...@@ -158,6 +159,10 @@ RSpec.configure do |config|
# Reload all feature flags definitions # Reload all feature flags definitions
Feature.register_definitions Feature.register_definitions
# Enable all features by default for testing
# Reset any changes in after hook.
stub_all_feature_flags
end end
config.after(:all) do config.after(:all) do
...@@ -176,9 +181,6 @@ RSpec.configure do |config| ...@@ -176,9 +181,6 @@ RSpec.configure do |config|
config.before do |example| config.before do |example|
if example.metadata.fetch(:stub_feature_flags, true) if example.metadata.fetch(:stub_feature_flags, true)
# Enable all features by default for testing
stub_all_feature_flags
# The following can be removed when we remove the staged rollout strategy # The following can be removed when we remove the staged rollout strategy
# and we can just enable it using instance wide settings # and we can just enable it using instance wide settings
# (ie. ApplicationSetting#auto_devops_enabled) # (ie. ApplicationSetting#auto_devops_enabled)
...@@ -203,6 +205,8 @@ RSpec.configure do |config| ...@@ -203,6 +205,8 @@ RSpec.configure do |config|
stub_feature_flags(file_identifier_hash: false) stub_feature_flags(file_identifier_hash: false)
allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(enable_rugged) allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(enable_rugged)
else
unstub_all_feature_flags
end end
# Enable Marginalia feature for all specs in the test suite. # Enable Marginalia feature for all specs in the test suite.
...@@ -314,6 +318,9 @@ RSpec.configure do |config| ...@@ -314,6 +318,9 @@ RSpec.configure do |config|
config.after do config.after do
Fog.unmock! if Fog.mock? Fog.unmock! if Fog.mock?
Gitlab::CurrentSettings.clear_in_memory_application_settings! Gitlab::CurrentSettings.clear_in_memory_application_settings!
# Reset all feature flag stubs to default for testing
stub_all_feature_flags
end end
config.before(:example, :mailer) do config.before(:example, :mailer) do
......
# frozen_string_literal: true # frozen_string_literal: true
module StubFeatureFlags module StubFeatureFlags
def self.included(base)
# Extend Feature class with methods that can stub feature flags.
Feature.prepend(StubbedFeature)
end
class StubFeatureGate class StubFeatureGate
attr_reader :flipper_id attr_reader :flipper_id
...@@ -9,28 +14,14 @@ module StubFeatureFlags ...@@ -9,28 +14,14 @@ module StubFeatureFlags
end end
end end
# Ensure feature flags are stubbed and reset.
def stub_all_feature_flags def stub_all_feature_flags
adapter = Flipper::Adapters::Memory.new Feature.stub = true
flipper = Flipper.new(adapter) Feature.reset_flipper
allow(Feature).to receive(:flipper).and_return(flipper)
# All new requested flags are enabled by default
allow(Feature).to receive(:enabled?).and_wrap_original do |m, *args|
feature_flag = m.call(*args)
# If feature flag is not persisted we mark the feature flag as enabled
# We do `m.call` as we want to validate the execution of method arguments
# and a feature flag state if it is not persisted
unless Feature.persisted_name?(args.first)
# TODO: this is hack to support `promo_feature_available?`
# We enable all feature flags by default unless they are `promo_`
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/218667
feature_flag = true unless args.first.to_s.start_with?('promo_')
end end
feature_flag def unstub_all_feature_flags
end Feature.stub = false
end end
# Stub Feature flags with `flag_name: true/false` # Stub Feature flags with `flag_name: true/false`
......
# frozen_string_literal: true
# Extend the Feature class with the ability to stub feature flags.
module StubbedFeature
extend ActiveSupport::Concern
class_methods do
# Turn stubbed feature flags on or off.
def stub=(stub)
@stub = stub
end
def stub?
@stub.nil? ? true : @stub
end
# Wipe any previously set feature flags.
def reset_flipper
@flipper = nil
end
# Replace #flipper method with the optional stubbed/unstubbed version.
def flipper
if stub?
@flipper ||= Flipper.new(Flipper::Adapters::Memory.new)
else
super
end
end
# Replace #enabled? method with the optional stubbed/unstubbed version.
def enabled?(*args)
feature_flag = super(*args)
return feature_flag unless stub?
# If feature flag is not persisted we mark the feature flag as enabled
# We do `m.call` as we want to validate the execution of method arguments
# and a feature flag state if it is not persisted
unless Feature.persisted_name?(args.first)
# TODO: this is hack to support `promo_feature_available?`
# We enable all feature flags by default unless they are `promo_`
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/218667
feature_flag = true unless args.first.to_s.start_with?('promo_')
end
feature_flag
end
end
end
...@@ -119,6 +119,42 @@ RSpec.describe StubFeatureFlags do ...@@ -119,6 +119,42 @@ RSpec.describe StubFeatureFlags do
end end
end end
describe 'stub timing' do
context 'let_it_be variable' do
let_it_be(:let_it_be_var) { Feature.enabled?(:any_feature_flag) }
it { expect(let_it_be_var).to eq true }
end
context 'before_all variable' do
before_all do
@suite_var = Feature.enabled?(:any_feature_flag)
end
it { expect(@suite_var).to eq true }
end
context 'before(:all) variable' do
before(:all) do
@suite_var = Feature.enabled?(:any_feature_flag)
end
it { expect(@suite_var).to eq true }
end
context 'with stub_feature_flags meta' do
let(:var) { Feature.enabled?(:any_feature_flag) }
context 'as true', :stub_feature_flags do
it { expect(var).to eq true }
end
context 'as false', stub_feature_flags: false do
it { expect(var).to eq false }
end
end
end
def actor(actor) def actor(actor)
case actor case actor
when Array when Array
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment