Some checks failed
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
Build & Push SDK Proto Builder / build (push) Has been cancelled
441 lines
13 KiB
Go
441 lines
13 KiB
Go
package config
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/spf13/viper"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
)
|
|
|
|
func TestDefaultConfig(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
require.True(t, cfg.GetMinGasPrices().IsZero())
|
|
}
|
|
|
|
func TestGetAndSetMinimumGas(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
|
|
input := sdk.DecCoins{sdk.NewInt64DecCoin("foo", 5)}
|
|
cfg.SetMinGasPrices(input)
|
|
require.Equal(t, "5.000000000000000000foo", cfg.MinGasPrices)
|
|
require.EqualValues(t, cfg.GetMinGasPrices(), input)
|
|
|
|
input = sdk.DecCoins{sdk.NewInt64DecCoin("bar", 1), sdk.NewInt64DecCoin("foo", 5)}
|
|
cfg.SetMinGasPrices(input)
|
|
require.Equal(t, "1.000000000000000000bar,5.000000000000000000foo", cfg.MinGasPrices)
|
|
require.EqualValues(t, cfg.GetMinGasPrices(), input)
|
|
}
|
|
|
|
func TestIndexEventsMarshalling(t *testing.T) {
|
|
expectedIn := `index-events = ["key1", "key2", ]` + "\n"
|
|
cfg := DefaultConfig()
|
|
cfg.IndexEvents = []string{"key1", "key2"}
|
|
var buffer bytes.Buffer
|
|
|
|
err := configTemplate.Execute(&buffer, cfg)
|
|
require.NoError(t, err, "executing template")
|
|
actual := buffer.String()
|
|
require.Contains(t, actual, expectedIn, "config file contents")
|
|
}
|
|
|
|
func TestStreamingConfig(t *testing.T) {
|
|
cfg := Config{
|
|
Streaming: StreamingConfig{
|
|
ABCI: ABCIListenerConfig{
|
|
Keys: []string{"one", "two"},
|
|
Plugin: "plugin-A",
|
|
StopNodeOnErr: false,
|
|
},
|
|
},
|
|
}
|
|
|
|
testDir := t.TempDir()
|
|
cfgFile := filepath.Join(testDir, "app.toml")
|
|
WriteConfigFile(cfgFile, &cfg)
|
|
|
|
cfgFileBz, err := os.ReadFile(cfgFile)
|
|
require.NoError(t, err, "reading %s", cfgFile)
|
|
cfgFileContents := string(cfgFileBz)
|
|
t.Logf("Config file contents: %s:\n%s", cfgFile, cfgFileContents)
|
|
|
|
expectedLines := []string{
|
|
`keys = ["one", "two", ]`,
|
|
`plugin = "plugin-A"`,
|
|
`stop-node-on-err = false`,
|
|
}
|
|
|
|
for _, line := range expectedLines {
|
|
assert.Contains(t, cfgFileContents, line+"\n", "config file contents")
|
|
}
|
|
|
|
vpr := viper.New()
|
|
vpr.SetConfigFile(cfgFile)
|
|
err = vpr.ReadInConfig()
|
|
require.NoError(t, err, "reading config file into viper")
|
|
|
|
var actual Config
|
|
err = vpr.Unmarshal(&actual)
|
|
require.NoError(t, err, "vpr.Unmarshal")
|
|
|
|
assert.Equal(t, cfg.Streaming, actual.Streaming, "Streaming")
|
|
}
|
|
|
|
func TestParseStreaming(t *testing.T) {
|
|
expectedKeys := `keys = ["*", ]` + "\n"
|
|
expectedPlugin := `plugin = "abci_v1"` + "\n"
|
|
expectedStopNodeOnErr := `stop-node-on-err = true` + "\n"
|
|
|
|
cfg := DefaultConfig()
|
|
cfg.Streaming.ABCI.Keys = []string{"*"}
|
|
cfg.Streaming.ABCI.Plugin = "abci_v1"
|
|
cfg.Streaming.ABCI.StopNodeOnErr = true
|
|
|
|
var buffer bytes.Buffer
|
|
err := configTemplate.Execute(&buffer, cfg)
|
|
require.NoError(t, err, "executing template")
|
|
actual := buffer.String()
|
|
require.Contains(t, actual, expectedKeys, "config file contents")
|
|
require.Contains(t, actual, expectedPlugin, "config file contents")
|
|
require.Contains(t, actual, expectedStopNodeOnErr, "config file contents")
|
|
}
|
|
|
|
func TestReadConfig(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
tmpFile := filepath.Join(t.TempDir(), "config")
|
|
WriteConfigFile(tmpFile, cfg)
|
|
|
|
v := viper.New()
|
|
otherCfg, err := GetConfig(v)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, *cfg, otherCfg)
|
|
}
|
|
|
|
func TestIndexEventsWriteRead(t *testing.T) {
|
|
expected := []string{"key3", "key4"}
|
|
|
|
// Create config with two IndexEvents entries, and write it to a file.
|
|
confFile := filepath.Join(t.TempDir(), "app.toml")
|
|
conf := DefaultConfig()
|
|
conf.IndexEvents = expected
|
|
|
|
WriteConfigFile(confFile, conf)
|
|
|
|
// read the file into Viper
|
|
vpr := viper.New()
|
|
vpr.SetConfigFile(confFile)
|
|
|
|
err := vpr.ReadInConfig()
|
|
require.NoError(t, err, "reading config file into viper")
|
|
|
|
// Check that the raw viper value is correct.
|
|
actualRaw := vpr.GetStringSlice("index-events")
|
|
require.Equal(t, expected, actualRaw, "viper's index events")
|
|
|
|
// Check that it is parsed into the config correctly.
|
|
cfg, perr := ParseConfig(vpr)
|
|
require.NoError(t, perr, "parsing config")
|
|
|
|
actual := cfg.IndexEvents
|
|
require.Equal(t, expected, actual, "config value")
|
|
}
|
|
|
|
func TestGlobalLabelsEventsMarshalling(t *testing.T) {
|
|
expectedIn := `global-labels = [
|
|
["labelname1", "labelvalue1"],
|
|
["labelname2", "labelvalue2"],
|
|
]`
|
|
cfg := DefaultConfig()
|
|
cfg.Telemetry.GlobalLabels = [][]string{{"labelname1", "labelvalue1"}, {"labelname2", "labelvalue2"}}
|
|
var buffer bytes.Buffer
|
|
|
|
err := configTemplate.Execute(&buffer, cfg)
|
|
require.NoError(t, err, "executing template")
|
|
actual := buffer.String()
|
|
require.Contains(t, actual, expectedIn, "config file contents")
|
|
}
|
|
|
|
func TestGlobalLabelsWriteRead(t *testing.T) {
|
|
expected := [][]string{{"labelname3", "labelvalue3"}, {"labelname4", "labelvalue4"}}
|
|
expectedRaw := make([]any, len(expected))
|
|
for i, exp := range expected {
|
|
pair := make([]any, len(exp))
|
|
for j, s := range exp {
|
|
pair[j] = s
|
|
}
|
|
expectedRaw[i] = pair
|
|
}
|
|
|
|
// Create config with two GlobalLabels entries, and write it to a file.
|
|
confFile := filepath.Join(t.TempDir(), "app.toml")
|
|
conf := DefaultConfig()
|
|
conf.Telemetry.GlobalLabels = expected
|
|
WriteConfigFile(confFile, conf)
|
|
|
|
// Read that file into viper.
|
|
vpr := viper.New()
|
|
vpr.SetConfigFile(confFile)
|
|
rerr := vpr.ReadInConfig()
|
|
require.NoError(t, rerr, "reading config file into viper")
|
|
// Check that the raw viper value is correct.
|
|
actualRaw := vpr.Get("telemetry.global-labels")
|
|
require.Equal(t, expectedRaw, actualRaw, "viper value")
|
|
// Check that it is parsed into the config correctly.
|
|
cfg, perr := ParseConfig(vpr)
|
|
require.NoError(t, perr, "parsing config")
|
|
actual := cfg.Telemetry.GlobalLabels
|
|
require.Equal(t, expected, actual, "config value")
|
|
}
|
|
|
|
func TestSetConfigTemplate(t *testing.T) {
|
|
conf := DefaultConfig()
|
|
var initBuffer, setBuffer bytes.Buffer
|
|
|
|
// Use the configTemplate defined during init() to create a config string.
|
|
ierr := configTemplate.Execute(&initBuffer, conf)
|
|
require.NoError(t, ierr, "initial configTemplate.Execute")
|
|
expected := initBuffer.String()
|
|
|
|
// Set the template to the default one.
|
|
initTmpl := configTemplate
|
|
require.NotPanics(t, func() {
|
|
SetConfigTemplate(DefaultConfigTemplate)
|
|
}, "SetConfigTemplate")
|
|
setTmpl := configTemplate
|
|
require.NotSame(t, initTmpl, setTmpl, "configTemplate after set")
|
|
|
|
// Create the string again and make sure it's the same.
|
|
serr := configTemplate.Execute(&setBuffer, conf)
|
|
require.NoError(t, serr, "after SetConfigTemplate, configTemplate.Execute")
|
|
actual := setBuffer.String()
|
|
require.Equal(t, expected, actual, "resulting config strings")
|
|
}
|
|
|
|
func TestAppConfig(t *testing.T) {
|
|
appConfigFile := filepath.Join(t.TempDir(), "app.toml")
|
|
defer func() {
|
|
_ = os.Remove(appConfigFile)
|
|
}()
|
|
|
|
defAppConfig := DefaultConfig()
|
|
SetConfigTemplate(DefaultConfigTemplate)
|
|
WriteConfigFile(appConfigFile, defAppConfig)
|
|
|
|
v := viper.New()
|
|
v.SetConfigFile(appConfigFile)
|
|
require.NoError(t, v.ReadInConfig())
|
|
appCfg := new(Config)
|
|
require.NoError(t, v.Unmarshal(appCfg))
|
|
require.EqualValues(t, appCfg, defAppConfig)
|
|
}
|
|
|
|
func TestGetConfig_HistoricalGRPCAddressBlockRange(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
setupViper func(*viper.Viper)
|
|
expectError bool
|
|
errorMsg string
|
|
validate func(*testing.T, Config)
|
|
}{
|
|
{
|
|
name: "valid single historical grpc address",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [0, 1000]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 1)
|
|
expectedRange := BlockRange{0, 1000}
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[expectedRange]
|
|
require.True(t, exists, "Block range [0, 1000] should exist")
|
|
require.Equal(t, "localhost:9091", address)
|
|
},
|
|
},
|
|
{
|
|
name: "valid multiple historical grpc addresses",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range",
|
|
`{"localhost:9091": [0, 1000], "localhost:9092": [1001, 2000], "localhost:9093": [2001, 3000]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 3)
|
|
testCases := []struct {
|
|
blockRange BlockRange
|
|
address string
|
|
}{
|
|
{BlockRange{0, 1000}, "localhost:9091"},
|
|
{BlockRange{1001, 2000}, "localhost:9092"},
|
|
{BlockRange{2001, 3000}, "localhost:9093"},
|
|
}
|
|
for _, tc := range testCases {
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[tc.blockRange]
|
|
require.True(t, exists, "Block range %v should exist", tc.blockRange)
|
|
require.Equal(t, tc.address, address)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "empty configuration",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", "")
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Nil(t, cfg.GRPC.HistoricalGRPCAddressBlockRange)
|
|
},
|
|
},
|
|
{
|
|
name: "no configuration set",
|
|
setupViper: func(v *viper.Viper) {},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Nil(t, cfg.GRPC.HistoricalGRPCAddressBlockRange)
|
|
},
|
|
},
|
|
{
|
|
name: "invalid JSON format",
|
|
setupViper: func(v *viper.Viper) {
|
|
// missing closing brace
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [0, 1000]`)
|
|
},
|
|
expectError: true,
|
|
errorMsg: "failed to parse historical-grpc-address-block-range as JSON",
|
|
},
|
|
{
|
|
name: "negative start block",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [-1, 1000]}`)
|
|
},
|
|
expectError: true,
|
|
errorMsg: "block numbers cannot be negative",
|
|
},
|
|
{
|
|
name: "negative end block",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [0, -100]}`)
|
|
},
|
|
expectError: true,
|
|
errorMsg: "block numbers cannot be negative",
|
|
},
|
|
{
|
|
name: "start block greater than end block",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [1000, 500]}`)
|
|
},
|
|
expectError: true,
|
|
errorMsg: "start block must be <= end block",
|
|
},
|
|
{
|
|
name: "single block range (start equals end)",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [1000, 1000]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 1)
|
|
expectedRange := BlockRange{1000, 1000}
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[expectedRange]
|
|
require.True(t, exists)
|
|
require.Equal(t, "localhost:9091", address)
|
|
},
|
|
},
|
|
{
|
|
name: "zero to zero range",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [0, 0]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 1)
|
|
expectedRange := BlockRange{0, 0}
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[expectedRange]
|
|
require.True(t, exists)
|
|
require.Equal(t, "localhost:9091", address)
|
|
},
|
|
},
|
|
{
|
|
name: "large block numbers",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [1000000, 2000000]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 1)
|
|
expectedRange := BlockRange{1000000, 2000000}
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[expectedRange]
|
|
require.True(t, exists)
|
|
require.Equal(t, "localhost:9091", address)
|
|
},
|
|
},
|
|
{
|
|
name: "invalid array length (too few elements)",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [100]}`)
|
|
},
|
|
expectError: true,
|
|
errorMsg: "start block must be <= end block",
|
|
},
|
|
{
|
|
name: "invalid array length (too many elements)",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"localhost:9091": [0, 1000, 2000]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 1)
|
|
expectedRange := BlockRange{0, 1000}
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[expectedRange]
|
|
require.True(t, exists)
|
|
require.Equal(t, "localhost:9091", address)
|
|
},
|
|
},
|
|
{
|
|
name: "address with port and protocol",
|
|
setupViper: func(v *viper.Viper) {
|
|
v.Set("grpc.historical-grpc-address-block-range", `{"https://archive.example.com:9091": [0, 1000]}`)
|
|
},
|
|
expectError: false,
|
|
validate: func(t *testing.T, cfg Config) {
|
|
t.Helper()
|
|
require.Len(t, cfg.GRPC.HistoricalGRPCAddressBlockRange, 1)
|
|
expectedRange := BlockRange{0, 1000}
|
|
address, exists := cfg.GRPC.HistoricalGRPCAddressBlockRange[expectedRange]
|
|
require.True(t, exists)
|
|
require.Equal(t, "https://archive.example.com:9091", address)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
v := viper.New()
|
|
v.Set("minimum-gas-prices", "0stake")
|
|
tt.setupViper(v)
|
|
cfg, err := GetConfig(v)
|
|
if tt.expectError {
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), tt.errorMsg)
|
|
} else {
|
|
require.NoError(t, err)
|
|
if tt.validate != nil {
|
|
tt.validate(t, cfg)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|