Class: LaunchDarkly::Integrations::TestDataV2
- Inherits:
-
Object
- Object
- LaunchDarkly::Integrations::TestDataV2
- Defined in:
- lib/ldclient-rb/integrations/test_data_v2.rb,
lib/ldclient-rb/integrations/test_data_v2/flag_builder_v2.rb
Overview
A mechanism for providing dynamically updatable feature flag state in a simplified form to an SDK client in test scenarios using the FDv2 protocol.
This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning. It is not suitable for production usage.
Do not use it. You have been warned.
Unlike FileData, this mechanism does not use any external resources. It provides only the data that the application has put into it using the #update method.
The above example uses a simple boolean flag, but more complex configurations are possible using the methods of the FlagBuilderV2 that is returned by #flag. FlagBuilderV2 supports many of the ways a flag can be configured on the LaunchDarkly dashboard, but does not currently support 1. rule operators other than “in” and “not in”, or 2. percentage rollouts.
If the same TestDataV2 instance is used to configure multiple LDClient instances, any changes made to the data will propagate to all of the LDClient instances.
Defined Under Namespace
Classes: FlagBuilderV2, FlagRuleBuilderV2
Constant Summary collapse
- TRUE_VARIATION_INDEX =
Constants for boolean flag variation indices
0- FALSE_VARIATION_INDEX =
1
Class Method Summary collapse
-
.data_source ⇒ TestDataV2
Creates a new instance of the test data source.
- .variation_for_boolean(variation) ⇒ Object private
Instance Method Summary collapse
- #add_instance(instance) ⇒ Object private
-
#build_initializer(sdk_key, config) ⇒ LaunchDarkly::Impl::Integrations::TestData::TestDataSourceV2
Creates an initializer that can be used with the FDv2 data system.
-
#build_synchronizer(sdk_key, config) ⇒ LaunchDarkly::Impl::Integrations::TestData::TestDataSourceV2
Creates a synchronizer that can be used with the FDv2 data system.
- #closed_instance(instance) ⇒ Object private
-
#flag(key) ⇒ FlagBuilderV2
Creates or copies a FlagBuilderV2 for building a test flag configuration.
- #get_version ⇒ Object private
-
#initialize ⇒ TestDataV2
constructor
private
A new instance of TestDataV2.
- #make_init_data ⇒ Object private
-
#update(flag_builder) ⇒ TestDataV2
Updates the test data with the specified flag configuration.
-
#use_preconfigured_segment(segment) ⇒ TestDataV2
Copies a full segment data model object into the test data.
Constructor Details
#initialize ⇒ TestDataV2
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of TestDataV2.
60 61 62 63 64 65 66 67 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 60 def initialize @flag_builders = Hash.new @current_flags = Hash.new @current_segments = Hash.new @lock = Concurrent::ReadWriteLock.new @instances = Array.new @version = 0 end |
Class Method Details
.data_source ⇒ TestDataV2
Creates a new instance of the test data source.
55 56 57 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 55 def self.data_source self.new end |
.variation_for_boolean(variation) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
13 14 15 |
# File 'lib/ldclient-rb/integrations/test_data_v2/flag_builder_v2.rb', line 13 def self.variation_for_boolean(variation) variation ? TRUE_VARIATION_INDEX : FALSE_VARIATION_INDEX end |
Instance Method Details
#add_instance(instance) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
168 169 170 171 172 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 168 def add_instance(instance) @lock.with_write_lock do @instances.push(instance) end end |
#build_initializer(sdk_key, config) ⇒ LaunchDarkly::Impl::Integrations::TestData::TestDataSourceV2
Creates an initializer that can be used with the FDv2 data system.
231 232 233 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 231 def build_initializer(sdk_key, config) LaunchDarkly::Impl::Integrations::TestData::TestDataSourceV2.new(self) end |
#build_synchronizer(sdk_key, config) ⇒ LaunchDarkly::Impl::Integrations::TestData::TestDataSourceV2
Creates a synchronizer that can be used with the FDv2 data system.
242 243 244 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 242 def build_synchronizer(sdk_key, config) LaunchDarkly::Impl::Integrations::TestData::TestDataSourceV2.new(self) end |
#closed_instance(instance) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
160 161 162 163 164 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 160 def closed_instance(instance) @lock.with_write_lock do @instances.delete(instance) if @instances.include?(instance) end end |
#flag(key) ⇒ FlagBuilderV2
Creates or copies a FlagBuilderV2 for building a test flag configuration.
If this flag key has already been defined in this TestDataV2 instance, then the builder starts with the same configuration that was last provided for this flag.
Otherwise, it starts with a new default configuration in which the flag has true and false variations, is true for all contexts when targeting is turned on and false otherwise, and currently has targeting turned on. You can change any of those properties, and provide more complex behavior, using the FlagBuilderV2 methods.
Once you have set the desired configuration, pass the builder to #update.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 85 def flag(key) existing_builder = @lock.with_read_lock do if @flag_builders.key?(key) && !@flag_builders[key].nil? @flag_builders[key] else nil end end if existing_builder.nil? LaunchDarkly::Integrations::TestDataV2::FlagBuilderV2.new(key).boolean_flag else existing_builder.clone end end |
#get_version ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
150 151 152 153 154 155 156 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 150 def get_version @lock.with_write_lock do version = @version @version += 1 version end end |
#make_init_data ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
140 141 142 143 144 145 146 147 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 140 def make_init_data @lock.with_read_lock do { flags: @current_flags.dup, segments: @current_segments.dup, } end end |
#update(flag_builder) ⇒ TestDataV2
Updates the test data with the specified flag configuration.
This has the same effect as if a flag were added or modified on the LaunchDarkly dashboard. It immediately propagates the flag change to any LDClient instance(s) that you have already configured to use this TestDataV2. If no LDClient has been started yet, it simply adds this flag to the test data which will be provided to any LDClient that you subsequently configure.
Any subsequent changes to this FlagBuilderV2 instance do not affect the test data, unless you call #update again.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 116 def update(flag_builder) instances_copy = [] new_flag = nil @lock.with_write_lock do old_flag = @current_flags[flag_builder._key] old_version = old_flag ? old_flag[:version] : 0 new_flag = flag_builder.build(old_version + 1) @current_flags[flag_builder._key] = new_flag @flag_builders[flag_builder._key] = flag_builder.clone # Create a copy of instances while holding the lock to avoid race conditions instances_copy = @instances.dup end instances_copy.each do |instance| instance.upsert_flag(new_flag) end self end |
#use_preconfigured_segment(segment) ⇒ TestDataV2
Copies a full segment data model object into the test data.
It immediately propagates the change to any LDClient instance(s) that you have already configured to use this TestDataV2. If no LDClient has been started yet, it simply adds this segment to the test data which will be provided to any LDClient that you subsequently configure.
This method is currently the only way to inject segment data, since there is no builder API for segments. It is mainly intended for the SDK’s own tests of segment functionality, since application tests that need to produce a desired evaluation state could do so more easily by just setting flag values.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/ldclient-rb/integrations/test_data_v2.rb', line 191 def use_preconfigured_segment(segment) instances_copy = [] segment_key = nil updated_segment = nil @lock.with_write_lock do # Convert to hash and normalize keys to symbols segment_hash = if segment.is_a?(Hash) segment.transform_keys(&:to_sym) else segment.as_json end segment_key = segment_hash[:key] old_segment = @current_segments[segment_key] old_version = old_segment ? old_segment[:version] : 0 updated_segment = segment_hash.dup updated_segment[:version] = old_version + 1 @current_segments[segment_key] = updated_segment # Create a copy of instances while holding the lock to avoid race conditions instances_copy = @instances.dup end instances_copy.each do |instance| instance.upsert_segment(updated_segment) end self end |