- 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)
- }
|