Skip to content

Commit

Permalink
Merge a1f4253 into e9a646e
Browse files Browse the repository at this point in the history
  • Loading branch information
yasirfolio3 committed Oct 31, 2019
2 parents e9a646e + a1f4253 commit 01870f0
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 4 deletions.
6 changes: 5 additions & 1 deletion pkg/config/datafileprojectconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ func NewDatafileProjectConfig(jsonDatafile []byte) (*DatafileProjectConfig, erro
}

attributeMap, attributeKeyToIDMap := mappers.MapAttributes(datafile.Attributes)
experimentMap, experimentKeyMap := mappers.MapExperiments(datafile.Experiments)
allExperiments := mappers.MergeExperiments(datafile.Experiments, datafile.Groups)
groupMap, experimentGroupMap := mappers.MapGroups(datafile.Groups)
experimentMap, experimentKeyMap := mappers.MapExperiments(allExperiments, experimentGroupMap)

rolloutMap := mappers.MapRollouts(datafile.Rollouts)
eventMap := mappers.MapEvents(datafile.Events)
mergedAudiences := append(datafile.TypedAudiences, datafile.Audiences...)
Expand All @@ -183,6 +186,7 @@ func NewDatafileProjectConfig(jsonDatafile []byte) (*DatafileProjectConfig, erro
botFiltering: datafile.BotFiltering,
experimentKeyToIDMap: experimentKeyMap,
experimentMap: experimentMap,
groupMap: groupMap,
eventMap: eventMap,
featureMap: mappers.MapFeatures(datafile.FeatureFlags, rolloutMap, experimentMap),
projectID: datafile.ProjectID,
Expand Down
9 changes: 9 additions & 0 deletions pkg/config/datafileprojectconfig/entities/entities.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ type Experiment struct {
AudienceConditions []interface{} `json:"audienceConditions"`
}

// Group represents an Group object from the Optimizely datafile
type Group struct {
ID string `json:"id"`
Policy string `json:"policy"`
TrafficAllocation []trafficAllocation `json:"trafficAllocation"`
Experiments []Experiment `json:"experiments"`
}

// FeatureFlag represents a FeatureFlag object from the Optimizely datafile
type FeatureFlag struct {
ID string `json:"id"`
Expand Down Expand Up @@ -100,6 +108,7 @@ type Datafile struct {
Attributes []Attribute `json:"attributes"`
Audiences []Audience `json:"audiences"`
Experiments []Experiment `json:"experiments"`
Groups []Group `json:"groups"`
FeatureFlags []FeatureFlag `json:"featureFlags"`
Events []Event `json:"events"`
Rollouts []Rollout `json:"rollouts"`
Expand Down
12 changes: 11 additions & 1 deletion pkg/config/datafileprojectconfig/mappers/experiment.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ import (
)

// MapExperiments maps the raw experiments entities from the datafile to SDK Experiment entities and also returns a map of experiment key to experiment ID
func MapExperiments(rawExperiments []datafileEntities.Experiment) (experimentMap map[string]entities.Experiment, experimentKeyMap map[string]string) {
func MapExperiments(rawExperiments []datafileEntities.Experiment, experimentGroupMap map[string]string) (experimentMap map[string]entities.Experiment, experimentKeyMap map[string]string) {

experimentMap = make(map[string]entities.Experiment)
experimentKeyMap = make(map[string]string)
for _, rawExperiment := range rawExperiments {

experiment := mapExperiment(rawExperiment)
experiment.GroupID = experimentGroupMap[experiment.ID]
experimentMap[experiment.ID] = experiment
experimentKeyMap[experiment.Key] = experiment.ID
}
Expand Down Expand Up @@ -89,3 +90,12 @@ func mapExperiment(rawExperiment datafileEntities.Experiment) entities.Experimen

return experiment
}

// MergeExperiments combines raw experiments and experiments inside groups and returns the array
func MergeExperiments(rawExperiments []datafileEntities.Experiment, rawGroups []datafileEntities.Group) (mergedExperiments []datafileEntities.Experiment) {
mergedExperiments = rawExperiments
for _, group := range rawGroups {
mergedExperiments = append(mergedExperiments, group.Experiments...)
}
return mergedExperiments
}
55 changes: 53 additions & 2 deletions pkg/config/datafileprojectconfig/mappers/experiment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,14 @@ func TestMapExperiments(t *testing.T) {
json.Unmarshal([]byte(testExperimentString), &rawExperiment)

rawExperiments := []datafileEntities.Experiment{rawExperiment}
experiments, experimentKeyMap := MapExperiments(rawExperiments)
experimentGroupMap := map[string]string{"11111": "15"}

experiments, experimentKeyMap := MapExperiments(rawExperiments, experimentGroupMap)
expectedExperiments := map[string]entities.Experiment{
"11111": {
AudienceIds: []string{"31111"},
ID: "11111",
GroupID: "15",
Key: "test_experiment_11111",
Variations: map[string]entities.Variation{
"21111": {
Expand Down Expand Up @@ -114,6 +117,53 @@ func TestMapExperiments(t *testing.T) {
assert.Equal(t, expectedExperimentKeyMap, experimentKeyMap)
}

func TestMergeExperiments(t *testing.T) {
const testExperimentString = `{
"id": "11111",
}`

const testGroupString = `{
"policy": "random",
"trafficAllocation": [
{
"entityId": "21113",
"endOfRange": 7000
},
{
"entityId": "21114",
"endOfRange": 10000
}
],
"experiments": [
{
"id": "11112"
}
],
"id":"11112"
}`

var rawExperiment datafileEntities.Experiment
var rawGroup datafileEntities.Group
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal([]byte(testExperimentString), &rawExperiment)
json.Unmarshal([]byte(testGroupString), &rawGroup)

rawExperiments := []datafileEntities.Experiment{rawExperiment}
rawGroups := []datafileEntities.Group{rawGroup}
mergedExperiments := MergeExperiments(rawExperiments, rawGroups)

expectedExperiments := []datafileEntities.Experiment{
{
ID: "11111",
},
{
ID: "11112",
},
}

assert.Equal(t, expectedExperiments, mergedExperiments)
}

func TestMapExperimentsAudienceIdsOnly(t *testing.T) {
var rawExperiment datafileEntities.Experiment
rawExperiment.AudienceIds = []string{"11111", "11112"}
Expand All @@ -138,6 +188,7 @@ func TestMapExperimentsAudienceIdsOnly(t *testing.T) {
},
},
}
experiments, _ := MapExperiments([]datafileEntities.Experiment{rawExperiment})

experiments, _ := MapExperiments([]datafileEntities.Experiment{rawExperiment}, map[string]string{})
assert.Equal(t, expectedExperiment.AudienceConditionTree, experiments[rawExperiment.ID].AudienceConditionTree)
}
43 changes: 43 additions & 0 deletions pkg/config/datafileprojectconfig/mappers/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/****************************************************************************
* Copyright 2019, Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/

// Package mappers ...
package mappers

import (
datafileEntities "github.com/optimizely/go-sdk/pkg/config/datafileprojectconfig/entities"
"github.com/optimizely/go-sdk/pkg/entities"
)

// MapGroups maps the raw group entity from the datafile to an SDK Group entity
func MapGroups(rawGroups []datafileEntities.Group) (groupMap map[string]entities.Group, experimentGroupMap map[string]string) {
groupMap = make(map[string]entities.Group)
experimentGroupMap = make(map[string]string)
for _, group := range rawGroups {
groupEntity := entities.Group{
ID: group.ID,
Policy: group.Policy,
}
for _, allocation := range group.TrafficAllocation {
groupEntity.TrafficAllocation = append(groupEntity.TrafficAllocation, entities.Range(allocation))
}
groupMap[group.ID] = groupEntity
for _, experiment := range group.Experiments {
experimentGroupMap[experiment.ID] = group.ID
}
}
return groupMap, experimentGroupMap
}
61 changes: 61 additions & 0 deletions pkg/config/datafileprojectconfig/mappers/group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/****************************************************************************
* Copyright 2019, Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/

package mappers

import (
"testing"

jsoniter "github.com/json-iterator/go"
datafileEntities "github.com/optimizely/go-sdk/pkg/config/datafileprojectconfig/entities"
"github.com/optimizely/go-sdk/pkg/entities"
"github.com/stretchr/testify/assert"
)

func TestMapGroups(t *testing.T) {
const testGroupString = `{
"policy": "random",
"trafficAllocation": [
{
"entityId": "13",
"endOfRange": 4000
}
],
"id": "14"
}`

var rawGroup datafileEntities.Group
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal([]byte(testGroupString), &rawGroup)

rawGroups := []datafileEntities.Group{rawGroup}
groupMap, _ := MapGroups(rawGroups)

expectedGroupsMap := map[string]entities.Group{
"14": entities.Group{
ID: "14",
Policy: "random",
TrafficAllocation: []entities.Range{
entities.Range{
EntityID: "13",
EndOfRange: 4000,
},
},
},
}

assert.Equal(t, expectedGroupsMap, groupMap)
}

0 comments on commit 01870f0

Please sign in to comment.