Skip to content

Commit

Permalink
add dedicated methods to create the flags
Browse files Browse the repository at this point in the history
  • Loading branch information
cwaldren-ld committed Oct 15, 2024
1 parent fae991f commit 43ad690
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 22 deletions.
65 changes: 58 additions & 7 deletions integrationtests/api_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (a *apiHelper) logResult(desc string, err error) error {
return nil
}
addInfo := ""
if gse, ok := err.(ldapi.GenericOpenAPIError); ok {
if gse, ok := err.(*ldapi.GenericOpenAPIError); ok {
body := string(gse.Body())
addInfo = " - " + string(body)
}
Expand Down Expand Up @@ -368,17 +368,68 @@ func (a *apiHelper) createFlag(
return nil
}

// createFlagInEnvironment sets up a flag with two variations. The first
// is served when the flag is off, and the second is served when it is on.
func (a *apiHelper) createFlagWithVariations(
proj projectInfo,
env environmentInfo,
flagKey string,
on bool,
variation1 ldvalue.Value,
variation2 ldvalue.Value,
) error {
flagPost := ldapi.FeatureFlagBody{
Name: flagKey,
Key: flagKey,
}

for _, value := range []ldvalue.Value{variation1, variation2} {
valueAsInterface := value.AsArbitraryValue()
flagPost.Variations = append(flagPost.Variations, ldapi.Variation{Value: &valueAsInterface})
}

_, _, err := a.apiClient.FeatureFlagsApi.
PostFeatureFlag(a.apiContext, proj.key).
FeatureFlagBody(flagPost).
Execute()

err = a.logResult("Create flag "+flagKey+" in "+proj.key, err)
if err != nil {
return err
}

envPrefix := fmt.Sprintf("/environments/%s", env.key)
patch := ldapi.PatchWithComment{
Patch: []ldapi.PatchOperation{
makePatch("replace", envPrefix+"/offVariation", 0),
makePatch("replace", envPrefix+"/fallthrough/variation", 1),
makePatch("replace", envPrefix+"/on", on),
},
}
_, _, err = a.apiClient.FeatureFlagsApi.
PatchFeatureFlag(a.apiContext, proj.key, flagKey).
PatchWithComment(patch).
Execute()

err = a.logResult("Configure flag "+flagKey+" for "+env.key, err)
if err != nil {
return err
}

return nil
}

func (a *apiHelper) createFlagWithPrerequisites(
proj projectInfo,
env environmentInfo,
flagKey string,
valueForEnv ldvalue.Value,
on bool,
variation1 ldvalue.Value,
variation2 ldvalue.Value,
prerequisites []ldapi.Prerequisite,
) error {

if err := a.createFlag(proj, []environmentInfo{env}, flagKey, func(info environmentInfo) ldvalue.Value {
return valueForEnv
}); err != nil {
if err := a.createFlagWithVariations(proj, env, flagKey, on, variation1, variation2); err != nil {
return err
}

Expand All @@ -388,8 +439,8 @@ func (a *apiHelper) createFlagWithPrerequisites(
Patch: []ldapi.PatchOperation{
makePatch("replace", envPrefix+"/prerequisites", prerequisites),
makePatch("replace", envPrefix+"/offVariation", 0),
makePatch("replace", envPrefix+"/on", true),
makePatch("replace", envPrefix+"/fallthrough/variation", 0),
makePatch("replace", envPrefix+"/on", on),
makePatch("replace", envPrefix+"/fallthrough/variation", 1),
},
}).Execute()

Expand Down
22 changes: 11 additions & 11 deletions integrationtests/standard_mode_prerequisite_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,44 @@ import (
"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
"github.com/stretchr/testify/require"
"testing"
"time"
)

func withStandardModePrerequisitesTestData(t *testing.T, manager *integrationTestManager, fn func(data standardModeTestData, prereqs map[string][]string)) {
project, envs, err := manager.apiHelper.createProject(1)
require.NoError(t, err)
defer manager.apiHelper.deleteProject(project)

trueVal := func(info environmentInfo) ldvalue.Value {
return ldvalue.Bool(true)
}

flagKey := func(name string) string {
return name + "-" + flagKeyForProj(project)
}

env := envs[0]
toplevel1 := flagKey("toplevel1")
prereq1 := flagKey("prereq1")
prereq2 := flagKey("prereq2")

err = manager.apiHelper.createFlag(project, envs, prereq1, trueVal)
err = manager.apiHelper.createFlagWithVariations(project, env, prereq1, true, ldvalue.Bool(false), ldvalue.Bool(true))
require.NoError(t, err)

err = manager.apiHelper.createFlag(project, envs, prereq2, trueVal)
err = manager.apiHelper.createFlagWithVariations(project, env, prereq2, true, ldvalue.Bool(false), ldvalue.Bool(true))
require.NoError(t, err)

prerequisites := map[string][]string{
toplevel1: {prereq1, prereq2},
}

// The createFlagWithVariations call sets up two variations, with the second one being used if the flag is on.
// The test here is to see which prerequisites were evaluated for a given flag. If a prerequisite fails, the eval
// algorithm is going to short-circuit and we won't see the other prerequisite. So, we'll have two prerequisites,
// both of which are on, and both of which are satisfied. That way the evaluator will be forced to visit both,
// and we'll see the list of both when we query the eval endpoint.
const onVariation = 1
for flag, prereqs := range prerequisites {
var ps []ldapi.Prerequisite
for _, prereq := range prereqs {
ps = append(ps, ldapi.Prerequisite{Key: prereq, Variation: 0})
ps = append(ps, ldapi.Prerequisite{Key: prereq, Variation: onVariation})
}
err = manager.apiHelper.createFlagWithPrerequisites(project, envs[0], flag, ldvalue.Bool(true), ps)
err = manager.apiHelper.createFlagWithPrerequisites(project, env, flag, true, ldvalue.Bool(false), ldvalue.Bool(true), ps)
require.NoError(t, err)
}

Expand All @@ -52,8 +54,6 @@ func withStandardModePrerequisitesTestData(t *testing.T, manager *integrationTes
},
}

// This is here because the backend takes a while to setup the filters, otherwise we get 404s when connecting.
time.Sleep(10 * time.Second)
fn(testData, prerequisites)
}

Expand Down
8 changes: 4 additions & 4 deletions integrationtests/test_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,11 @@ func (m *integrationTestManager) verifyFlagPrerequisites(t *testing.T, projsAndE
t.Fail()
continue
}
for i, prereqKey := range prereqKeys {
if prereqArray.Get(i).String() != prereqKey {
for i, expectedPrereqKey := range prereqKeys {
actualPrereqKey := prereqArray.Get(i).StringValue()
if expectedPrereqKey != actualPrereqKey {
m.loggers.Errorf("Expected flag %s to have prerequisite %s at index %d, but it had %s",
flagKey, prereqKey, i, prereqArray.Get(i).String())
t.Fail()
flagKey, expectedPrereqKey, i, actualPrereqKey)
}
}
}
Expand Down

0 comments on commit 43ad690

Please sign in to comment.