* initial commit * add support of integerts * finialise the static provider * minor refactoring * the rest * revert: the rest * add new thiongs * more tests added * add ff parsing tests to check if types are handled correctly * update tests according to recent changes * address golint issues * Update pkg/setting/setting_feature_toggles.go Co-authored-by: Dave Henderson <dave.henderson@grafana.com> * fix rebase issues * addressing review comments * add test cases for enterprise * handle enterprise cases * minor refactoring to make api a bit easier to debug * make test names a bit more precise * fix linter * add openfeature sdk to goleak ignore in testutil * Remove only boolean check in ff gen tests * add non-boolean types top the doc in default.ini and doc string in FeatureFlag type * apply remarks, add docs to sample.ini * reflect changes in feature flags in the public grafana configuration doc * fix doc formatting * apply suggestions to the doc file --------- Co-authored-by: Dave Henderson <dave.henderson@grafana.com>
112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
package setting
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/open-feature/go-sdk/openfeature/memprovider"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gopkg.in/ini.v1"
|
|
)
|
|
|
|
func TestFeatureToggles(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
conf map[string]string
|
|
expectedToggles map[string]memprovider.InMemoryFlag
|
|
}{
|
|
{
|
|
name: "can parse feature toggles passed in the `enable` array",
|
|
conf: map[string]string{
|
|
"enable": "feature1,feature2",
|
|
},
|
|
expectedToggles: map[string]memprovider.InMemoryFlag{
|
|
"feature1": NewInMemoryFlag("feature1", true),
|
|
"feature2": NewInMemoryFlag("feature2", true),
|
|
},
|
|
},
|
|
{
|
|
name: "can parse feature toggles listed under [feature_toggles]",
|
|
conf: map[string]string{
|
|
"enable": "feature1,feature2",
|
|
"feature3": "true",
|
|
},
|
|
expectedToggles: map[string]memprovider.InMemoryFlag{
|
|
"feature1": NewInMemoryFlag("feature1", true),
|
|
"feature2": NewInMemoryFlag("feature2", true),
|
|
"feature3": NewInMemoryFlag("feature3", true),
|
|
},
|
|
},
|
|
{
|
|
name: "toggles under [feature_toggles] overrides those in the array",
|
|
conf: map[string]string{
|
|
"enable": "feature1,feature2",
|
|
"feature2": "false",
|
|
},
|
|
expectedToggles: map[string]memprovider.InMemoryFlag{
|
|
"feature1": NewInMemoryFlag("feature1", true),
|
|
"feature2": NewInMemoryFlag("feature2", false),
|
|
},
|
|
},
|
|
{
|
|
name: "feature flags of different types are handled correctly",
|
|
conf: map[string]string{
|
|
"feature1": "1", "feature2": "1.0",
|
|
"feature3": `{"foo":"bar"}`, "feature4": "bar",
|
|
"feature5": "t", "feature6": "T",
|
|
},
|
|
expectedToggles: map[string]memprovider.InMemoryFlag{
|
|
"feature1": NewInMemoryFlag("feature1", 1),
|
|
"feature2": NewInMemoryFlag("feature2", 1.0),
|
|
"feature3": NewInMemoryFlag("feature3", map[string]any{"foo": "bar"}),
|
|
"feature4": NewInMemoryFlag("feature4", "bar"),
|
|
"feature5": NewInMemoryFlag("feature5", true),
|
|
"feature6": NewInMemoryFlag("feature6", true),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
f := ini.Empty()
|
|
|
|
toggles, _ := f.NewSection("feature_toggles")
|
|
for k, v := range tc.conf {
|
|
_, err := toggles.NewKey(k, v)
|
|
require.ErrorIs(t, err, nil)
|
|
}
|
|
|
|
featureToggles, err := ReadFeatureTogglesFromInitFile(toggles)
|
|
require.NoError(t, err)
|
|
|
|
for k, v := range featureToggles {
|
|
toggle := tc.expectedToggles[k]
|
|
require.Equal(t, toggle, v, tc.name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFlagValueSerialization(t *testing.T) {
|
|
testCases := []memprovider.InMemoryFlag{
|
|
NewInMemoryFlag("int", 1),
|
|
NewInMemoryFlag("1.0f", 1.0),
|
|
NewInMemoryFlag("1.01f", 1.01),
|
|
NewInMemoryFlag("1.10f", 1.10),
|
|
NewInMemoryFlag("struct", map[string]any{"foo": "bar"}),
|
|
NewInMemoryFlag("string", "bar"),
|
|
NewInMemoryFlag("true", true),
|
|
NewInMemoryFlag("false", false),
|
|
}
|
|
|
|
for _, tt := range testCases {
|
|
asStringMap := AsStringMap(map[string]memprovider.InMemoryFlag{tt.Key: tt})
|
|
|
|
deserialized, err := ParseFlag(tt.Key, asStringMap[tt.Key])
|
|
assert.NoError(t, err)
|
|
|
|
if diff := cmp.Diff(tt, deserialized); diff != "" {
|
|
t.Errorf("(-want, +got) = %v", diff)
|
|
}
|
|
}
|
|
}
|