diff --git a/splitio/sdk/conf/conf.go b/splitio/sdk/conf/conf.go index 1d2a9d0..f06d900 100644 --- a/splitio/sdk/conf/conf.go +++ b/splitio/sdk/conf/conf.go @@ -15,14 +15,15 @@ const ( ) type Config struct { - LabelsEnabled bool - StreamingEnabled bool - Splits Splits - Segments Segments - Impressions Impressions - Events Events - URLs URLs - FlagSetsFilter []string + LabelsEnabled bool + StreamingEnabled bool + Splits Splits + Segments Segments + Impressions Impressions + Events Events + URLs URLs + FlagSetsFilter []string + FallbackTreatment dtos.FallbackTreatmentConfig } type Splits struct { @@ -81,6 +82,7 @@ func (c *Config) ToAdvancedConfig() *conf.AdvancedConfig { d.ImpressionsQueueSize = c.Impressions.QueueSize d.AuthSpecVersion = specs.FLAG_V1_1 d.FlagsSpecVersion = specs.FLAG_V1_1 + d.FallbackTreatment = c.FallbackTreatment return &d } diff --git a/splitio/sdk/integration_test.go b/splitio/sdk/integration_test.go index a906782..aba90b7 100644 --- a/splitio/sdk/integration_test.go +++ b/splitio/sdk/integration_test.go @@ -104,6 +104,20 @@ func TestInstantiationAndGetTreatmentE2E(t *testing.T) { sdkConf.URLs.SDK = sdkServer.URL sdkConf.URLs.Telemetry = telemetryServer.URL sdkConf.StreamingEnabled = false + stringConfig := "flag1_config" + globalTreatment := "global_treatment" + flag1Treatment := "flag1_treatment" + sdkConf.FallbackTreatment = dtos.FallbackTreatmentConfig{ + GlobalFallbackTreatment: &dtos.FallbackTreatment{ + Treatment: &globalTreatment, + }, + ByFlagFallbackTreatment: map[string]dtos.FallbackTreatment{ + "flag1": { + Treatment: &flag1Treatment, + Config: &stringConfig, + }, + }, + } logger := logging.NewLogger(nil) client, err := New(logger, "someApikey", sdkConf) @@ -115,3 +129,115 @@ func TestInstantiationAndGetTreatmentE2E(t *testing.T) { assert.Nil(t, client.Shutdown()) assert.Equal(t, int32(1), atomic.LoadInt32(&eventsCalls)) } + +func TestInstantiationAndGetTreatmentE2EWithFallbackTreatment(t *testing.T) { + metricsInitCalled := 0 + mockedSplit1 := dtos.SplitDTO{ + Algo: 2, + ChangeNumber: 123, + DefaultTreatment: "default", + Killed: false, + Name: "split", + Seed: 1234, + Status: "ACTIVE", + TrafficAllocation: 1, + TrafficAllocationSeed: -1667452163, + TrafficTypeName: "tt1", + Conditions: []dtos.ConditionDTO{ + { + ConditionType: "ROLLOUT", + Label: "in segment all", + MatcherGroup: dtos.MatcherGroupDTO{ + Combiner: "AND", + Matchers: []dtos.MatcherDTO{{MatcherType: "ALL_KEYS"}}, + }, + Partitions: []dtos.PartitionDTO{{Size: 100, Treatment: "on"}}, + }, + }, + } + mockedSplit2 := dtos.SplitDTO{Name: "split2", Killed: true, Status: "ACTIVE"} + mockedSplit3 := dtos.SplitDTO{Name: "split3", Killed: true, Status: "INACTIVE"} + + sdkServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method) + assert.Equal(t, "/splitChanges", r.URL.Path) + + splitChanges := dtos.RuleChangesDTO{ + FeatureFlags: dtos.FeatureFlagsDTO{ + Splits: []dtos.SplitDTO{mockedSplit1, mockedSplit2, mockedSplit3}, + Since: 3, + Till: 3, + }, + } + + assert.Equal(t, "-1", r.URL.Query().Get("since")) + assert.Equal(t, specs.FLAG_V1_3, r.URL.Query().Get("s")) + + raw, err := json.Marshal(splitChanges) + assert.Nil(t, err) + + w.Write(raw) + })) + defer sdkServer.Close() + + var eventsCalls int32 + eventsServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + atomic.AddInt32(&eventsCalls, 1) + assert.Equal(t, "POST", r.Method) + assert.Equal(t, "/testImpressions/bulk", r.URL.Path) + + body, err := io.ReadAll(r.Body) + assert.Nil(t, err) + + var imps []dtos.ImpressionsDTO + assert.Nil(t, json.Unmarshal(body, &imps)) + + assert.Equal(t, "not_exist", imps[0].TestName) + assert.Equal(t, 1, len(imps[0].KeyImpressions)) + w.WriteHeader(200) + })) + defer eventsServer.Close() + + telemetryServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/metrics/config": + metricsInitCalled++ + rBody, _ := ioutil.ReadAll(r.Body) + var dataInPost dtos.Config + err := json.Unmarshal(rBody, &dataInPost) + assert.Nil(t, err) + } + fmt.Fprintln(w, "ok") + })) + defer telemetryServer.Close() + + sdkConf := conf.DefaultConfig() + sdkConf.URLs.Events = eventsServer.URL + sdkConf.URLs.SDK = sdkServer.URL + sdkConf.URLs.Telemetry = telemetryServer.URL + sdkConf.StreamingEnabled = false + stringConfig := "flag1_config" + globalTreatment := "global_treatment" + flag1Treatment := "flag1_treatment" + sdkConf.FallbackTreatment = dtos.FallbackTreatmentConfig{ + GlobalFallbackTreatment: &dtos.FallbackTreatment{ + Treatment: &globalTreatment, + }, + ByFlagFallbackTreatment: map[string]dtos.FallbackTreatment{ + "flag1": { + Treatment: &flag1Treatment, + Config: &stringConfig, + }, + }, + } + + logger := logging.NewLogger(nil) + client, err := New(logger, "someApikey", sdkConf) + assert.Nil(t, err) + + res1, _ := client.Treatment(&types.ClientConfig{}, "aaaaaaklmnbv", nil, "not_exist", nil) + assert.Equal(t, "global_treatment", res1.Treatment) + + assert.Nil(t, client.Shutdown()) + assert.Equal(t, int32(1), atomic.LoadInt32(&eventsCalls)) +}