-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from ResultadosDigitais/ns-releases-migration
Adds possibility to migrate feature_keys to resource_keys
- Loading branch information
Showing
5 changed files
with
142 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# frozen_string_literal: true | ||
|
||
module FeatureFlagger | ||
module Storage | ||
class FeatureKeysMigration | ||
|
||
def initialize(from_redis, to_control) | ||
@from_redis = from_redis | ||
@to_control = to_control | ||
end | ||
|
||
# call migrates features key from the old fashioned to the new | ||
# format. | ||
# | ||
# It must replicate feature keys with changes: | ||
# | ||
# from "avenue:traffic_lights" => 42 | ||
# to "avenue:42" => traffic_lights | ||
def call | ||
@from_redis.scan_each(match: "*", count: FeatureFlagger::Storage::Redis::SCAN_EACH_BATCH_SIZE) do |redis_key| | ||
# filter out resource_keys | ||
next if redis_key.start_with?("#{FeatureFlagger::Storage::Redis::RESOURCE_PREFIX}:") | ||
|
||
migrate_key(redis_key) | ||
end | ||
end | ||
|
||
private | ||
|
||
def migrate_key(key) | ||
return migrate_release_to_all(key) if feature_released_to_all?(key) | ||
|
||
migrate_release(key) | ||
end | ||
|
||
def migrate_release_to_all(key) | ||
features = @from_redis.smembers(key) | ||
|
||
features.each do |feature_key| | ||
@to_control.release_to_all(feature_key) | ||
end | ||
end | ||
|
||
def feature_released_to_all?(key) | ||
FeatureFlagger::Control::RELEASED_FEATURES == key | ||
end | ||
|
||
def migrate_release(key) | ||
resource_ids = @from_redis.smembers(key) | ||
|
||
@to_control.release(key, resource_ids) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
spec/feature_flagger/storage/feature_keys_migration_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
require 'feature_flagger/storage/feature_keys_migration' | ||
|
||
RSpec.describe FeatureFlagger::Storage::FeatureKeysMigration do | ||
subject(:migrator) { described_class.new(redis, control) } | ||
|
||
let(:redis) { FakeRedis::Redis.new } | ||
let(:control) { FeatureFlagger::Control.new(FeatureFlagger::Storage::Redis.new(redis)) } | ||
let(:global_key) { FeatureFlagger::Control::RELEASED_FEATURES } | ||
|
||
before do | ||
filepath = File.expand_path('../fixtures/rollout_example.yml', __dir__) | ||
FeatureFlagger.config.yaml_filepath = filepath | ||
end | ||
|
||
describe '.call' do | ||
context 'when there are keys in the old format' do | ||
before do | ||
redis.sadd('feature_flagger_dummy_class:email_marketing:behavior_score', 42) | ||
redis.sadd('feature_flagger_dummy_class:email_marketing:whitelabel', 42) | ||
redis.sadd('feature_flagger_dummy_class:email_marketing:whitelabel', 1) | ||
redis.sadd(global_key, 'other_feature_flagger_dummy_class:feature_c:feature_c_1') | ||
redis.sadd(global_key, 'other_feature_flagger_dummy_class:feature_c:feature_c_2') | ||
redis.sadd(global_key, 'account') | ||
|
||
migrator.call | ||
end | ||
|
||
it 'migrates feature keys to the new format' do | ||
expect(control.released?('feature_flagger_dummy_class:email_marketing:behavior_score', 42)).to be_truthy | ||
expect(control.released?('feature_flagger_dummy_class:email_marketing:whitelabel', 42)).to be_truthy | ||
expect(control.released?('feature_flagger_dummy_class:email_marketing:whitelabel', 1)).to be_truthy | ||
end | ||
|
||
it 'migrates all released feature keys to the new format' do | ||
expect(control.released_to_all?('other_feature_flagger_dummy_class:feature_c:feature_c_2')).to be_truthy | ||
expect(control.released_to_all?('other_feature_flagger_dummy_class:feature_c:feature_c_1')).to be_truthy | ||
end | ||
end | ||
|
||
context 'when there are keys in both formats' do | ||
before do | ||
redis.sadd('feature_flagger_dummy_class:email_marketing:behavior_score', 42) | ||
redis.sadd('feature_flagger_dummy_class:email_marketing:whitelabel', 42) | ||
redis.sadd('feature_flagger_dummy_class:email_marketing:whitelabel', 1) | ||
redis.sadd(global_key, 'feature_flagger_dummy_class:email_marketing:whitelabel') | ||
|
||
control.release('other_feature_flagger_dummy_class:feature_b', 42) | ||
control.release_to_all('other_feature_flagger_dummy_class:feature_c:feature_c_1') | ||
|
||
migrator.call | ||
end | ||
|
||
it 'migrates feature keys to the new format' do | ||
expect(control.released?('feature_flagger_dummy_class:email_marketing:behavior_score', 42)).to be_truthy | ||
expect(control.released?('feature_flagger_dummy_class:email_marketing:whitelabel', 42)).to be_truthy | ||
expect(control.released?('feature_flagger_dummy_class:email_marketing:whitelabel', 1)).to be_truthy | ||
expect(control.released?('other_feature_flagger_dummy_class:feature_b', 42)).to be_truthy | ||
end | ||
|
||
it 'does not migrate internal keys' do | ||
expect(redis.keys.count).to eq(7) | ||
end | ||
|
||
it 'migrates all released feature keys to the new format ' do | ||
expect(control.released_to_all?('feature_flagger_dummy_class:email_marketing:whitelabel')).to be_truthy | ||
expect(control.released_to_all?('other_feature_flagger_dummy_class:feature_c:feature_c_1')).to be_truthy | ||
end | ||
end | ||
end | ||
end |