package commands
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
cfg "github.com/tendermint/tendermint/config"
|
|
"github.com/tendermint/tendermint/libs/cli"
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
tmos "github.com/tendermint/tendermint/libs/os"
|
|
)
|
|
|
|
// writeConfigVals writes a toml file with the given values.
|
|
// It returns an error if writing was impossible.
|
|
func writeConfigVals(dir string, vals map[string]string) error {
|
|
data := ""
|
|
for k, v := range vals {
|
|
data += fmt.Sprintf("%s = \"%s\"\n", k, v)
|
|
}
|
|
cfile := filepath.Join(dir, "config.toml")
|
|
return os.WriteFile(cfile, []byte(data), 0600)
|
|
}
|
|
|
|
// clearConfig clears env vars, the given root dir, and resets viper.
|
|
func clearConfig(t *testing.T, dir string) *cfg.Config {
|
|
t.Helper()
|
|
require.NoError(t, os.Unsetenv("TMHOME"))
|
|
require.NoError(t, os.Unsetenv("TM_HOME"))
|
|
require.NoError(t, os.RemoveAll(dir))
|
|
|
|
viper.Reset()
|
|
conf := cfg.DefaultConfig()
|
|
conf.RootDir = dir
|
|
return conf
|
|
}
|
|
|
|
// prepare new rootCmd
|
|
func testRootCmd(conf *cfg.Config) *cobra.Command {
|
|
logger := log.NewNopLogger()
|
|
cmd := RootCommand(conf, logger)
|
|
cmd.RunE = func(cmd *cobra.Command, args []string) error { return nil }
|
|
|
|
var l string
|
|
cmd.PersistentFlags().String("log", l, "Log")
|
|
return cmd
|
|
}
|
|
|
|
func testSetup(ctx context.Context, t *testing.T, conf *cfg.Config, args []string, env map[string]string) error {
|
|
t.Helper()
|
|
|
|
cmd := testRootCmd(conf)
|
|
viper.Set(cli.HomeFlag, conf.RootDir)
|
|
|
|
// run with the args and env
|
|
args = append([]string{cmd.Use}, args...)
|
|
return cli.RunWithArgs(ctx, cmd, args, env)
|
|
}
|
|
|
|
func TestRootHome(t *testing.T) {
|
|
defaultRoot := t.TempDir()
|
|
newRoot := filepath.Join(defaultRoot, "something-else")
|
|
cases := []struct {
|
|
args []string
|
|
env map[string]string
|
|
root string
|
|
}{
|
|
{nil, nil, defaultRoot},
|
|
{[]string{"--home", newRoot}, nil, newRoot},
|
|
{nil, map[string]string{"TMHOME": newRoot}, newRoot},
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
for i, tc := range cases {
|
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
|
conf := clearConfig(t, tc.root)
|
|
|
|
err := testSetup(ctx, t, conf, tc.args, tc.env)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tc.root, conf.RootDir)
|
|
require.Equal(t, tc.root, conf.P2P.RootDir)
|
|
require.Equal(t, tc.root, conf.Consensus.RootDir)
|
|
require.Equal(t, tc.root, conf.Mempool.RootDir)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRootFlagsEnv(t *testing.T) {
|
|
// defaults
|
|
defaults := cfg.DefaultConfig()
|
|
defaultDir := t.TempDir()
|
|
|
|
defaultLogLvl := defaults.LogLevel
|
|
|
|
cases := []struct {
|
|
args []string
|
|
env map[string]string
|
|
logLevel string
|
|
}{
|
|
{[]string{"--log", "debug"}, nil, defaultLogLvl}, // wrong flag
|
|
{[]string{"--log-level", "debug"}, nil, "debug"}, // right flag
|
|
{nil, map[string]string{"TM_LOW": "debug"}, defaultLogLvl}, // wrong env flag
|
|
{nil, map[string]string{"MT_LOG_LEVEL": "debug"}, defaultLogLvl}, // wrong env prefix
|
|
{nil, map[string]string{"TM_LOG_LEVEL": "debug"}, "debug"}, // right env
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
for i, tc := range cases {
|
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
|
conf := clearConfig(t, defaultDir)
|
|
|
|
err := testSetup(ctx, t, conf, tc.args, tc.env)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tc.logLevel, conf.LogLevel)
|
|
})
|
|
|
|
}
|
|
}
|
|
|
|
func TestRootConfig(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
// write non-default config
|
|
nonDefaultLogLvl := "debug"
|
|
cvals := map[string]string{
|
|
"log-level": nonDefaultLogLvl,
|
|
}
|
|
|
|
cases := []struct {
|
|
args []string
|
|
env map[string]string
|
|
logLvl string
|
|
}{
|
|
{nil, nil, nonDefaultLogLvl}, // should load config
|
|
{[]string{"--log-level=info"}, nil, "info"}, // flag over rides
|
|
{nil, map[string]string{"TM_LOG_LEVEL": "info"}, "info"}, // env over rides
|
|
}
|
|
|
|
for i, tc := range cases {
|
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
|
defaultRoot := t.TempDir()
|
|
conf := clearConfig(t, defaultRoot)
|
|
conf.LogLevel = tc.logLvl
|
|
|
|
// XXX: path must match cfg.defaultConfigPath
|
|
configFilePath := filepath.Join(defaultRoot, "config")
|
|
err := tmos.EnsureDir(configFilePath, 0700)
|
|
require.NoError(t, err)
|
|
|
|
// write the non-defaults to a different path
|
|
// TODO: support writing sub configs so we can test that too
|
|
err = writeConfigVals(configFilePath, cvals)
|
|
require.NoError(t, err)
|
|
|
|
cmd := testRootCmd(conf)
|
|
|
|
// run with the args and env
|
|
tc.args = append([]string{cmd.Use}, tc.args...)
|
|
err = cli.RunWithArgs(ctx, cmd, tc.args, tc.env)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tc.logLvl, conf.LogLevel)
|
|
})
|
|
}
|
|
}
|
|
|
|
// WriteConfigVals writes a toml file with the given values.
|
|
// It returns an error if writing was impossible.
|
|
func WriteConfigVals(dir string, vals map[string]string) error {
|
|
data := ""
|
|
for k, v := range vals {
|
|
data += fmt.Sprintf("%s = \"%s\"\n", k, v)
|
|
}
|
|
cfile := filepath.Join(dir, "config.toml")
|
|
return os.WriteFile(cfile, []byte(data), 0600)
|
|
}
|