Class: LaunchDarkly::Integrations::TestData
- Inherits:
-
Object
- Object
- LaunchDarkly::Integrations::TestData
- Defined in:
- lib/ldclient-rb/integrations/test_data.rb,
lib/ldclient-rb/integrations/test_data/flag_builder.rb
Overview
A mechanism for providing dynamically updatable feature flag state in a simplified form to an SDK client in test scenarios.
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 FlagBuilder that is returned by #flag. FlagBuilder 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 ‘TestData` instance is used to configure multiple `LDClient` instances, any changes made to the data will propagate to all of the `LDClient`s.
Defined Under Namespace
Classes: FlagBuilder
Class Method Summary collapse
-
.data_source ⇒ TestData
Creates a new instance of the test data source.
Instance Method Summary collapse
-
#arity ⇒ Object
Called internally by the SDK to determine what arguments to pass to call You do not need to call this method.
-
#call(_, config) ⇒ Object
Called internally by the SDK to associate this test data source with an LDClient instance.
- #closed_instance(instance) ⇒ Object
-
#flag(key) ⇒ FlagBuilder
Creates or copies a FlagBuilder for building a test flag configuration.
-
#initialize ⇒ TestData
constructor
A new instance of TestData.
- #make_init_data ⇒ Object
-
#update(flag_builder) ⇒ TestData
Updates the test data with the specified flag configuration.
-
#use_preconfigured_flag(flag) ⇒ TestData
Copies a full feature flag data model object into the test data.
-
#use_preconfigured_segment(segment) ⇒ TestData
Copies a full segment data model object into the test data.
Constructor Details
#initialize ⇒ TestData
Returns a new instance of TestData.
46 47 48 49 50 51 52 53 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 46 def initialize @flag_builders = Hash.new @current_flags = Hash.new @current_segments = Hash.new @instances = Array.new @instances_lock = Concurrent::ReadWriteLock.new @lock = Concurrent::ReadWriteLock.new end |
Class Method Details
.data_source ⇒ TestData
Creates a new instance of the test data source.
41 42 43 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 41 def self.data_source self.new end |
Instance Method Details
#arity ⇒ Object
Called internally by the SDK to determine what arguments to pass to call You do not need to call this method.
60 61 62 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 60 def arity 2 end |
#call(_, config) ⇒ Object
Called internally by the SDK to associate this test data source with an LDClient instance. You do not need to call this method.
69 70 71 72 73 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 69 def call(_, config) impl = LaunchDarkly::Impl::Integrations::TestData::TestDataSource.new(config.feature_store, self) @instances_lock.with_write_lock { @instances.push(impl) } impl end |
#closed_instance(instance) ⇒ Object
208 209 210 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 208 def closed_instance(instance) @instances_lock.with_write_lock { @instances.delete(instance) } end |
#flag(key) ⇒ FlagBuilder
Creates or copies a FlagBuilder for building a test flag configuration.
If this flag key has already been defined in this ‘TestData` 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 FlagBuilder methods.
Once you have set the desired configuration, pass the builder to #update.
91 92 93 94 95 96 97 98 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 91 def flag(key) existing_builder = @lock.with_read_lock { @flag_builders[key] } if existing_builder.nil? FlagBuilder.new(key).boolean_flag else existing_builder.clone end end |
#make_init_data ⇒ Object
198 199 200 201 202 203 204 205 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 198 def make_init_data @lock.with_read_lock do { FEATURES => @current_flags.clone, SEGMENTS => @current_segments.clone, } end end |
#update(flag_builder) ⇒ TestData
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 `TestData`. 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 FlagBuilder instance do not affect the test data, unless you call #update again.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 115 def update(flag_builder) new_flag = nil @lock.with_write_lock do @flag_builders[flag_builder.key] = flag_builder version = 0 flag_key = flag_builder.key.to_sym if @current_flags[flag_key] version = @current_flags[flag_key][:version] end new_flag = Impl::Model.deserialize(FEATURES, flag_builder.build(version+1)) @current_flags[flag_key] = new_flag end update_item(FEATURES, new_flag) self end |
#use_preconfigured_flag(flag) ⇒ TestData
Copies a full feature flag data model object into the test data.
It immediately propagates the flag change to any ‘LDClient` instance(s) that you have already configured to use this `TestData`. 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.
Use this method if you need to use advanced flag configuration properties that are not supported by the simplified FlagBuilder API. Otherwise it is recommended to use the regular #flag/#update mechanism to avoid dependencies on details of the data model.
You cannot make incremental changes with #flag/#update to a flag that has been added in this way; you can only replace it with an entirely new flag configuration.
149 150 151 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 149 def use_preconfigured_flag(flag) use_preconfigured_item(FEATURES, flag, @current_flags) end |
#use_preconfigured_segment(segment) ⇒ TestData
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 `TestData`. 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.
169 170 171 |
# File 'lib/ldclient-rb/integrations/test_data.rb', line 169 def use_preconfigured_segment(segment) use_preconfigured_item(SEGMENTS, segment, @current_segments) end |