Documentation ¶
Overview ¶
Package ldtestdata provides a mechanism for providing dynamically updatable feature flag state in a simplified form to an SDK client in test scenarios. The entry point for using this feature is DataSource.
Unlike the file data source (in the github.com/launchdarkly/go-server-sdk/v6/ldfiledata package), this mechanism does not use any external resources. It provides only the data that the application has put into it using the Update method.
td := ldtestdata.DataSource() td.Update(td.Flag("flag-key-1").BooleanFlag().VariationForAll(true)) config := ld.Config{ DataSource: td, } client := ld.MakeCustomClient(sdkKey, config, timeout) // flags can be updated at any time: td.Update(td.Flag("flag-key-2"). VariationForUser("some-user-key", true). FallthroughVariation(false))
The above example uses a simple boolean flag, but more complex configurations are possible using the methods of the FlagBuilder that is returned by TestDataSource.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 TestDataSource instance is used to configure multiple LDClient instances, any change made to the data will propagate to all of the LDClients.
Index ¶
- type FlagBuilder
- func (f *FlagBuilder) BooleanFlag() *FlagBuilder
- func (f *FlagBuilder) ClearRules() *FlagBuilder
- func (f *FlagBuilder) ClearTargets() *FlagBuilder
- func (f *FlagBuilder) FallthroughVariation(variation bool) *FlagBuilder
- func (f *FlagBuilder) FallthroughVariationIndex(variationIndex int) *FlagBuilder
- func (f *FlagBuilder) IfMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
- func (f *FlagBuilder) IfMatchContext(contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value) *RuleBuilder
- func (f *FlagBuilder) IfNotMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
- func (f *FlagBuilder) IfNotMatchContext(contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value) *RuleBuilder
- func (f *FlagBuilder) OffVariation(variation bool) *FlagBuilder
- func (f *FlagBuilder) OffVariationIndex(variationIndex int) *FlagBuilder
- func (f *FlagBuilder) On(on bool) *FlagBuilder
- func (f *FlagBuilder) ValueForAll(value ldvalue.Value) *FlagBuilder
- func (f *FlagBuilder) VariationForAll(variation bool) *FlagBuilder
- func (f *FlagBuilder) VariationForAllIndex(variationIndex int) *FlagBuilder
- func (f *FlagBuilder) VariationForKey(contextKind ldcontext.Kind, key string, variation bool) *FlagBuilder
- func (f *FlagBuilder) VariationForUser(userKey string, variation bool) *FlagBuilder
- func (f *FlagBuilder) VariationIndexForKey(contextKind ldcontext.Kind, key string, variationIndex int) *FlagBuilder
- func (f *FlagBuilder) VariationIndexForUser(userKey string, variationIndex int) *FlagBuilder
- func (f *FlagBuilder) Variations(values ...ldvalue.Value) *FlagBuilder
- type RuleBuilder
- func (r *RuleBuilder) AndMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
- func (r *RuleBuilder) AndMatchContext(contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value) *RuleBuilder
- func (r *RuleBuilder) AndNotMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
- func (r *RuleBuilder) AndNotMatchContext(contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value) *RuleBuilder
- func (r *RuleBuilder) ThenReturn(variation bool) *FlagBuilder
- func (r *RuleBuilder) ThenReturnIndex(variation int) *FlagBuilder
- type TestDataSource
- func (t *TestDataSource) Build(context subsystems.ClientContext) (subsystems.DataSource, error)
- func (t *TestDataSource) Flag(key string) *FlagBuilder
- func (t *TestDataSource) Update(flagBuilder *FlagBuilder) *TestDataSource
- func (t *TestDataSource) UpdateStatus(newState interfaces.DataSourceState, newError interfaces.DataSourceErrorInfo) *TestDataSource
- func (t *TestDataSource) UsePreconfiguredFlag(flag ldmodel.FeatureFlag) *TestDataSource
- func (t *TestDataSource) UsePreconfiguredSegment(segment ldmodel.Segment) *TestDataSource
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FlagBuilder ¶
type FlagBuilder struct {
// contains filtered or unexported fields
}
FlagBuilder is a builder for feature flag configurations to be used with TestDataSource.
func (*FlagBuilder) BooleanFlag ¶
func (f *FlagBuilder) BooleanFlag() *FlagBuilder
BooleanFlag is a shortcut for setting the flag to use the standard boolean configuration.
This is the default for all new flags created with TestDataSource.Flag. The flag will have two variations, true and false (in that order); it will return false whenever targeting is off, and true when targeting is on if no other settings specify otherwise.
func (*FlagBuilder) ClearRules ¶
func (f *FlagBuilder) ClearRules() *FlagBuilder
ClearRules removes any existing rules from the flag. This undoes the effect of methods like FlagBuilder.IfMatch.
func (*FlagBuilder) ClearTargets ¶
func (f *FlagBuilder) ClearTargets() *FlagBuilder
ClearTargets removes any existing user targets from the flag. This undoes the effect of methods like FlagBuilder.VariationForUser.
func (*FlagBuilder) FallthroughVariation ¶
func (f *FlagBuilder) FallthroughVariation(variation bool) *FlagBuilder
FallthroughVariation specifies the fallthrough variation for a boolean flag. The fallthrough is the value that is returned if targeting is on and the user was not matched by a more specific target or rule.
If the flag was previously configured with other variations, this also changes it to a boolean boolean flag.
To specify the variation by variation index instead (such as for a non-boolean flag), use FlagBuilder.FallthroughVariationIndex.
func (*FlagBuilder) FallthroughVariationIndex ¶
func (f *FlagBuilder) FallthroughVariationIndex(variationIndex int) *FlagBuilder
FallthroughVariationIndex specifies the index of the fallthrough variation. The fallthrough is the value that is returned if targeting is on and the user was not matched by a more specific target or rule. The index is 0 for the first variation, 1 for the second, etc.
To specify the variation as true or false instead, for a boolean flag, use FlagBuilder.FallthroughVariation.
func (*FlagBuilder) IfMatch ¶
func (f *FlagBuilder) IfMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
IfMatch starts defining a flag rule, using the "is one of" operator. This is a shortcut for calling FlagBuilder.IfMatchContext with "user" as the context kind.
The method returns a RuleBuilder. Call its RuleBuilder.ThenReturn or RuleBuilder.ThenReturnIndex method to finish the rule, or add more tests with another method like RuleBuilder.AndMatch.
For example, this creates a rule that returns true if the user name attribute is "Patsy" or "Edina":
testData.Flag("flag"). IfMatch("name", ldvalue.String("Patsy"), ldvalue.String("Edina")). ThenReturn(true)
func (*FlagBuilder) IfMatchContext ¶
func (f *FlagBuilder) IfMatchContext( contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value, ) *RuleBuilder
IfMatchContext starts defining a flag rule, using the "is one of" operator. This matching expression only applies to contexts of a specific kind, identified by the contextKind parameter.
The method returns a RuleBuilder. Call its RuleBuilder.ThenReturn or RuleBuilder.ThenReturnIndex method to finish the rule, or add more tests with another method like RuleBuilder.AndMatch.
For example, this creates a rule that returns true if the name attribute for the "company" context is "Ella" or "Monsoon":
testData.Flag("flag"). IfMatchContext("company", "name", ldvalue.String("Ella"), ldvalue.String("Monsoon")). ThenReturn(true)
func (*FlagBuilder) IfNotMatch ¶
func (f *FlagBuilder) IfNotMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
IfNotMatch starts defining a flag rule, using the "is not one of" operator. This is a shortcut for calling FlagBuilder.IfNotMatchContext with "user" as the context kind.
The method returns a RuleBuilder. Call its RuleBuilder.ThenReturn or RuleBuilder.ThenReturnIndex method to finish the rule, or add more tests with another method like RuleBuilder.AndMatch.
For example, this creates a rule that returns true if the user name attribute is neither "Saffron" nor "Bubble":
testData.Flag("flag"). IfNotMatch("name", ldvalue.String("Saffron"), ldvalue.String("Bubble")). ThenReturn(true)
func (*FlagBuilder) IfNotMatchContext ¶
func (f *FlagBuilder) IfNotMatchContext( contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value, ) *RuleBuilder
IfNotMatchContext starts defining a flag rule, using the "is not one of" operator. This matching expression only applies to contexts of a specific kind, identified by the contextKind parameter.
The method returns a RuleBuilder. Call its RuleBuilder.ThenReturn or RuleBuilder.ThenReturnIndex method to finish the rule, or add more tests with another method like RuleBuilder.AndMatch.
For example, this creates a rule that returns true if the name attribute for the "company" context is neither "Pendant" nor "Sterling Cooper":
testData.Flag("flag"). IfNotMatch("company", "name", ldvalue.String("Pendant"), ldvalue.String("Sterling Cooper")). ThenReturn(true)
func (*FlagBuilder) OffVariation ¶
func (f *FlagBuilder) OffVariation(variation bool) *FlagBuilder
OffVariation specifies the off variation for a boolean flag. This is the variation that is returned whenever targeting is off.
If the flag was previously configured with other variations, this also changes it to a boolean boolean flag.
To specify the variation by variation index instead (such as for a non-boolean flag), use FlagBuilder.OffVariationIndex.
func (*FlagBuilder) OffVariationIndex ¶
func (f *FlagBuilder) OffVariationIndex(variationIndex int) *FlagBuilder
OffVariationIndex specifies the index of the off variation. This is the variation that is returned whenever targeting is off. The index is 0 for the first variation, 1 for the second, etc.
To specify the variation as true or false instead, for a boolean flag, use FlagBuilder.OffVariation.
func (*FlagBuilder) On ¶
func (f *FlagBuilder) On(on bool) *FlagBuilder
On sets targeting to be on or off for this flag.
The effect of this depends on the rest of the flag configuration, just as it does on the real LaunchDarkly dashboard. In the default configuration that you get from calling TestDataSource.Flag with a new flag key, the flag will return false whenever targeting is off, and true when targeting is on.
func (*FlagBuilder) ValueForAll ¶
func (f *FlagBuilder) ValueForAll(value ldvalue.Value) *FlagBuilder
ValueForAll sets the flag to always return the specified variation value for all contexts.
The value may be of any JSON type, as defined by ldvalue.Value. This method changes the flag to only a single variation, which is this value, and to return the same variation regardless of whether targeting is on or off. Any existing targets or rules are removed.
func (*FlagBuilder) VariationForAll ¶
func (f *FlagBuilder) VariationForAll(variation bool) *FlagBuilder
VariationForAll sets the flag to return the specified boolean variation by default for all contexts.
Targeting is switched on, any existing targets or rules are removed, and the flag's variations are set to true and false. The fallthrough variation is set to the specified value. The off variation is left unchanged.
To specify the variation by variation index instead (such as for a non-boolean flag), use FlagBuilder.VariationForAllIndex.
func (*FlagBuilder) VariationForAllIndex ¶
func (f *FlagBuilder) VariationForAllIndex(variationIndex int) *FlagBuilder
VariationForAllIndex sets the flag to always return the specified variation for all contexts. The index is 0 for the first variation, 1 for the second, etc.
Targeting is switched on, and any existing targets or rules are removed. The fallthrough variation is set to the specified value. The off variation is left unchanged.
To specify the variation as true or false instead, for a boolean flag, use FlagBuilder.VariationForAll.
func (*FlagBuilder) VariationForKey ¶
func (f *FlagBuilder) VariationForKey(contextKind ldcontext.Kind, key string, variation bool) *FlagBuilder
VariationForKey sets the flag to return the specified boolean variation for a specific context, identified by context kind and key, when targeting is on.
This has no effect when targeting is turned off for the flag.
If the flag was not already a boolean flag, this also changes it to a boolean flag.
To specify the variation by variation index instead (such as for a non-boolean flag), use FlagBuilder.VariationIndexForKey.
func (*FlagBuilder) VariationForUser ¶
func (f *FlagBuilder) VariationForUser(userKey string, variation bool) *FlagBuilder
VariationForUser sets the flag to return the specified boolean variation for a specific user key (that is, for a context with that key whose context kind is "user") when targeting is on.
This has no effect when targeting is turned off for the flag.
If the flag was not already a boolean flag, this also changes it to a boolean flag.
To specify the variation by variation index instead (such as for a non-boolean flag), use FlagBuilder.VariationIndexForUser.
func (*FlagBuilder) VariationIndexForKey ¶
func (f *FlagBuilder) VariationIndexForKey(contextKind ldcontext.Kind, key string, variationIndex int) *FlagBuilder
VariationIndexForKey sets the flag to return the specified variation for a specific context, identified by context kind and key, when targeting is on. The index is 0 for the first variation, 1 for the second, etc.
This has no effect when targeting is turned off for the flag.
To specify the variation as a true or false value if it is a boolean flag, you can use FlagBuilder.VariationForKey instead.
func (*FlagBuilder) VariationIndexForUser ¶
func (f *FlagBuilder) VariationIndexForUser(userKey string, variationIndex int) *FlagBuilder
VariationIndexForUser sets the flag to return the specified variation for a specific user key (that is, for a context with that key whose context kind is "user") when targeting is on. The index is 0 for the first variation, 1 for the second, etc.
This has no effect when targeting is turned off for the flag.
To specify the variation as a true or false value if it is a boolean flag, you can use FlagBuilder.VariationForUser instead.
func (*FlagBuilder) Variations ¶
func (f *FlagBuilder) Variations(values ...ldvalue.Value) *FlagBuilder
Variations changes the allowable variation values for the flag.
The values may be of any JSON type, as defined by ldvalue.Value. For instance, a boolean flag normally has ldvalue.Bool(true), ldvalue.Bool(false); a string-valued flag might have ldvalue.String("red"), ldvalue.String("green")}; etc.
type RuleBuilder ¶
type RuleBuilder struct {
// contains filtered or unexported fields
}
RuleBuilder is a builder for feature flag rules to be used with [TestDataSource.]
In the LaunchDarkly model, a flag can have any number of rules, and a rule can have any number of clauses. A clause is an individual test such as "name is 'X'". A rule matches a user if all of the rule's clauses match the user.
To start defining a rule, use one of the flag builder's matching methods such as [RuleBuilder.IfMatch]. This defines the first clause for the rule. Optionally, you may add more clauses with the rule builder's methods such as RuleBuilder.AndMatch. Finally, call RuleBuilder.ThenReturn or RuleBuilder.ThenReturnIndex to finish defining the rule.
func (*RuleBuilder) AndMatch ¶
func (r *RuleBuilder) AndMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
AndMatch adds another clause, using the "is one of" operator. This is a shortcut for calling RuleBuilder.AndMatchContext with "user" as the context kind.
For example, this creates a rule that returns true if the user name attribute is "Patsy" and the country is "gb":
testData.Flag("flag"). IfMatch("name", ldvalue.String("Patsy")). AndMatch("country", ldvalue.String("gb")). ThenReturn(true)
func (*RuleBuilder) AndMatchContext ¶
func (r *RuleBuilder) AndMatchContext( contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value, ) *RuleBuilder
AndMatchContext adds another clause, using the "is one of" operator. This matching expression only applies to contexts of a specific kind, identified by the contextKind parameter.
For example, this creates a rule that returns true if the name attribute for the "company" context is "Ella" and the country is "gb":
testData.Flag("flag"). IfMatchContext("company", "name", ldvalue.String("Ella")). AndMatchContext("company", "country", ldvalue.String("gb")). ThenReturn(true)
func (*RuleBuilder) AndNotMatch ¶
func (r *RuleBuilder) AndNotMatch(attribute string, values ...ldvalue.Value) *RuleBuilder
AndNotMatch adds another clause, using the "is not one of" operator. This is a shortcut for calling RuleBuilder.AndNotMatchContext with "user" as the context kind.
For example, this creates a rule that returns true if the user name attribute is "Patsy" and the country is not "gb":
testData.Flag("flag"). IfMatch("name", ldvalue.String("Patsy")). AndNotMatch("country", ldvalue.String("gb")). ThenReturn(true)
func (*RuleBuilder) AndNotMatchContext ¶
func (r *RuleBuilder) AndNotMatchContext( contextKind ldcontext.Kind, attribute string, values ...ldvalue.Value, ) *RuleBuilder
AndNotMatchContext adds another clause, using the "is not one of" operator. This matching expression only applies to contexts of a specific kind, identified by the contextKind parameter.
For example, this creates a rule that returns true if the name attribute for the "company" context is "Ella" and the country is not "gb":
testData.Flag("flag"). IfMatchContext("company", "name", ldvalue.String("Ella")). AndNotMatchContext("company", "country", ldvalue.String("gb")). ThenReturn(true)
func (*RuleBuilder) ThenReturn ¶
func (r *RuleBuilder) ThenReturn(variation bool) *FlagBuilder
ThenReturn finishes defining the rule, specifying the result value as a boolean.
func (*RuleBuilder) ThenReturnIndex ¶
func (r *RuleBuilder) ThenReturnIndex(variation int) *FlagBuilder
ThenReturnIndex finishes defining the rule, specifying the result as a variation index. The index is 0 for the first variation, 1 for the second, etc.
type TestDataSource ¶
type TestDataSource struct {
// contains filtered or unexported fields
}
TestDataSource is a test fixture that provides dynamically updatable feature flag state in a simplified form to an SDK client in test scenarios.
See package description for more details and usage examples.
func DataSource ¶
func DataSource() *TestDataSource
DataSource creates an instance of TestDataSource.
Storing this object in the DataSource field of github.com/launchdarkly/go-server-sdk/v6.Config causes the SDK client to use the test data. Any subsequent changes made using methods like TestDataSource.Update will propagate to all LDClient instances that are using this data source.
func (*TestDataSource) Build ¶
func (t *TestDataSource) Build(context subsystems.ClientContext) (subsystems.DataSource, error)
Build is called internally by the SDK to associate this test data source with an LDClient instance. You do not need to call this method.
func (*TestDataSource) Flag ¶
func (t *TestDataSource) Flag(key string) *FlagBuilder
Flag creates or copies a FlagBuilder for building a test flag configuration.
If this flag key has already been defined in this TestDataSource 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 users 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.
func (*TestDataSource) Update ¶
func (t *TestDataSource) Update(flagBuilder *FlagBuilder) *TestDataSource
Update 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 TestDataSource. 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.
func (*TestDataSource) UpdateStatus ¶
func (t *TestDataSource) UpdateStatus( newState interfaces.DataSourceState, newError interfaces.DataSourceErrorInfo, ) *TestDataSource
UpdateStatus simulates a change in the data source status.
Use this if you want to test the behavior of application code that uses LDClient.GetDataSourceStatusProvider to track whether the data source is having problems (for example, a network failure interruptsingthe streaming connection). It does not actually stop the TestDataSource from working, so even if you have simulated an outage, calling Update will still send updates.
func (*TestDataSource) UsePreconfiguredFlag ¶
func (t *TestDataSource) UsePreconfiguredFlag(flag ldmodel.FeatureFlag) *TestDataSource
UsePreconfiguredFlag 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 TestDataSource. 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.
To construct an instance of ldmodel.FeatureFlag, rather than accessing the fields directly it is recommended to use the builder API in github.com/launchdarkly/go-server-sdk-evaluation/v2/ldbuilders.
func (*TestDataSource) UsePreconfiguredSegment ¶
func (t *TestDataSource) UsePreconfiguredSegment(segment ldmodel.Segment) *TestDataSource
UsePreconfiguredSegment copies a full user segment 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 TestDataSource. 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.
This method is currently the only way to inject user segment data, since there is no builder API for segments. It is mainly intended for the SDK's own tests of user segment functionality, since application tests that need to produce a desired evaluation state could do so more easily by just setting flag values.
To construct an instance of ldmodel.Segment, rather than accessing the fields directly it is recommended to use the builder API in github.com/launchdarkly/go-server-sdk-evaluation/v2/ldbuilders.