Skip to content

Commit

Permalink
added map support for over writable configs
Browse files Browse the repository at this point in the history
  • Loading branch information
axenteoctavian committed Apr 12, 2024
1 parent d9412ac commit a67343d
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 8 deletions.
21 changes: 21 additions & 0 deletions common/reflectcommon/structFieldsUpdate.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ func trySetTheNewValue(value *reflect.Value, newValue interface{}) error {
structVal := reflect.ValueOf(newValue)

return trySetStructValue(value, structVal)
case reflect.Map:
mapValue := reflect.ValueOf(newValue)

return tryUpdateMapValue(value, mapValue)
default:
return fmt.Errorf("unsupported type <%s> when trying to set the value '%v' of type <%s>", valueKind, newValue, reflect.TypeOf(newValue))
}
Expand Down Expand Up @@ -163,6 +167,23 @@ func trySetStructValue(value *reflect.Value, newValue reflect.Value) error {
}
}

func tryUpdateMapValue(value *reflect.Value, newValue reflect.Value) error {
if value.IsNil() {
value.Set(reflect.MakeMap(value.Type()))
}

switch newValue.Kind() {
case reflect.Map:
for _, key := range newValue.MapKeys() {
value.SetMapIndex(key, newValue.MapIndex(key))
}
default:
return fmt.Errorf("unsupported type <%s> when trying to add value in type <%s>", newValue.Kind(), value.Kind())
}

return nil
}

func updateStructFromMap(value *reflect.Value, newValue reflect.Value) error {
for _, key := range newValue.MapKeys() {
fieldName := key.String()
Expand Down
55 changes: 52 additions & 3 deletions common/reflectcommon/structFieldsUpdate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import (
"reflect"
"testing"

"github.com/multiversx/mx-chain-core-go/core"
"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/testscommon/toml"

"github.com/multiversx/mx-chain-core-go/core"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -447,10 +448,10 @@ func TestAdaptStructureValueBasedOnPath(t *testing.T) {
expectedNewValue["first"] = 1
expectedNewValue["second"] = 2

path := "TestMap.Value"
path := "TestInterface.Value"

err = AdaptStructureValueBasedOnPath(testConfig, path, expectedNewValue)
require.Equal(t, "unsupported type <map> when trying to set the value 'map[first:1 second:2]' of type <map[string]int>", err.Error())
require.Equal(t, "unsupported type <interface> when trying to set the value 'map[first:1 second:2]' of type <map[string]int>", err.Error())
})

t.Run("should error fit signed for target type not int", func(t *testing.T) {
Expand Down Expand Up @@ -1193,6 +1194,54 @@ func TestAdaptStructureValueBasedOnPath(t *testing.T) {
require.Equal(t, expectedNewValue, testConfig.TestConfigNestedStruct.ConfigNestedStruct.Message.MessageDescription)
})

t.Run("should work on map and override existing value in map", func(t *testing.T) {
t.Parallel()

testConfig, err := loadTestConfig("../../testscommon/toml/config.toml")
require.NoError(t, err)

expectedNewValue := make(map[string]int)
expectedNewValue["key"] = 100

path := "TestMap.Value"

err = AdaptStructureValueBasedOnPath(testConfig, path, expectedNewValue)
require.NoError(t, err)
require.Equal(t, 1, len(testConfig.TestMap.Value))
require.Equal(t, testConfig.TestMap.Value["key"], 100)
})

t.Run("should work on map and insert values in map", func(t *testing.T) {
t.Parallel()

testConfig, err := loadTestConfig("../../testscommon/toml/config.toml")
require.NoError(t, err)

expectedNewValue := make(map[string]int)
expectedNewValue["first"] = 1
expectedNewValue["second"] = 2

path := "TestMap.Value"

err = AdaptStructureValueBasedOnPath(testConfig, path, expectedNewValue)
require.NoError(t, err)
require.Equal(t, 3, len(testConfig.TestMap.Value))
})

t.Run("should error on map when override anything else other than map", func(t *testing.T) {
t.Parallel()

testConfig, err := loadTestConfig("../../testscommon/toml/config.toml")
require.NoError(t, err)

expectedNewValue := 1

path := "TestMap.Value"

err = AdaptStructureValueBasedOnPath(testConfig, path, expectedNewValue)
require.Equal(t, "unsupported type <int> when trying to add value in type <map>", err.Error())
})

}

func loadTestConfig(filepath string) (*toml.Config, error) {
Expand Down
10 changes: 5 additions & 5 deletions config/overridableConfig/configOverriding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/multiversx/mx-chain-go/config"
p2pConfig "github.com/multiversx/mx-chain-go/p2p/config"

"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -104,16 +105,15 @@ func TestOverrideConfigValues(t *testing.T) {
})

t.Run("should work for enableRounds.toml", func(t *testing.T) {
// TODO: fix this test
t.Skip("skipped, as this test requires the fix from this PR: https://github.com/multiversx/mx-chain-go/pull/5851")

t.Parallel()

configs := &config.Configs{RoundConfig: &config.RoundConfig{}}
value := make(map[string]config.ActivationRoundByName)
value["DisableAsyncCallV1"] = config.ActivationRoundByName{Round: "37"}

err := OverrideConfigValues([]config.OverridableConfig{{Path: "RoundActivations.DisableAsyncCallV1.Round", Value: "37", File: "enableRounds.toml"}}, configs)
err := OverrideConfigValues([]config.OverridableConfig{{Path: "RoundActivations", Value: value, File: "enableRounds.toml"}}, configs)
require.NoError(t, err)
require.Equal(t, uint32(37), configs.RoundConfig.RoundActivations["DisableAsyncCallV1"])
require.Equal(t, "37", configs.RoundConfig.RoundActivations["DisableAsyncCallV1"].Round)
})

t.Run("should work for ratings.toml", func(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions testscommon/toml/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Config struct {
TestConfigStruct
TestConfigNestedStruct
TestMap
TestInterface
}

// TestConfigI8 will hold an int8 value for testing
Expand Down Expand Up @@ -169,3 +170,8 @@ type MessageDescriptionOtherName struct {
type TestMap struct {
Value map[string]int
}

// TestInterface will hold an interface for testing
type TestInterface struct {
Value interface{}
}

0 comments on commit a67343d

Please sign in to comment.