github.com/vipernet-xyz/tm@v0.34.24/cmd/tendermint/commands/root_test.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strconv"
     8  	"testing"
     9  
    10  	"github.com/spf13/cobra"
    11  	"github.com/spf13/viper"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	cfg "github.com/vipernet-xyz/tm/config"
    16  	"github.com/vipernet-xyz/tm/libs/cli"
    17  	tmos "github.com/vipernet-xyz/tm/libs/os"
    18  )
    19  
    20  var defaultRoot = os.ExpandEnv("$HOME/.some/test/dir")
    21  
    22  // clearConfig clears env vars, the given root dir, and resets viper.
    23  func clearConfig(dir string) {
    24  	if err := os.Unsetenv("TMHOME"); err != nil {
    25  		panic(err)
    26  	}
    27  	if err := os.Unsetenv("TM_HOME"); err != nil {
    28  		panic(err)
    29  	}
    30  
    31  	if err := os.RemoveAll(dir); err != nil {
    32  		panic(err)
    33  	}
    34  	viper.Reset()
    35  	config = cfg.DefaultConfig()
    36  }
    37  
    38  // prepare new rootCmd
    39  func testRootCmd() *cobra.Command {
    40  	rootCmd := &cobra.Command{
    41  		Use:               RootCmd.Use,
    42  		PersistentPreRunE: RootCmd.PersistentPreRunE,
    43  		Run:               func(cmd *cobra.Command, args []string) {},
    44  	}
    45  	registerFlagsRootCmd(rootCmd)
    46  	var l string
    47  	rootCmd.PersistentFlags().String("log", l, "Log")
    48  	return rootCmd
    49  }
    50  
    51  func testSetup(rootDir string, args []string, env map[string]string) error {
    52  	clearConfig(defaultRoot)
    53  
    54  	rootCmd := testRootCmd()
    55  	cmd := cli.PrepareBaseCmd(rootCmd, "TM", defaultRoot)
    56  
    57  	// run with the args and env
    58  	args = append([]string{rootCmd.Use}, args...)
    59  	return cli.RunWithArgs(cmd, args, env)
    60  }
    61  
    62  func TestRootHome(t *testing.T) {
    63  	newRoot := filepath.Join(defaultRoot, "something-else")
    64  	cases := []struct {
    65  		args []string
    66  		env  map[string]string
    67  		root string
    68  	}{
    69  		{nil, nil, defaultRoot},
    70  		{[]string{"--home", newRoot}, nil, newRoot},
    71  		{nil, map[string]string{"TMHOME": newRoot}, newRoot},
    72  	}
    73  
    74  	for i, tc := range cases {
    75  		idxString := strconv.Itoa(i)
    76  
    77  		err := testSetup(defaultRoot, tc.args, tc.env)
    78  		require.Nil(t, err, idxString)
    79  
    80  		assert.Equal(t, tc.root, config.RootDir, idxString)
    81  		assert.Equal(t, tc.root, config.P2P.RootDir, idxString)
    82  		assert.Equal(t, tc.root, config.Consensus.RootDir, idxString)
    83  		assert.Equal(t, tc.root, config.Mempool.RootDir, idxString)
    84  	}
    85  }
    86  
    87  func TestRootFlagsEnv(t *testing.T) {
    88  	// defaults
    89  	defaults := cfg.DefaultConfig()
    90  	defaultLogLvl := defaults.LogLevel
    91  
    92  	cases := []struct {
    93  		args     []string
    94  		env      map[string]string
    95  		logLevel string
    96  	}{
    97  		{[]string{"--log", "debug"}, nil, defaultLogLvl},                 // wrong flag
    98  		{[]string{"--log_level", "debug"}, nil, "debug"},                 // right flag
    99  		{nil, map[string]string{"TM_LOW": "debug"}, defaultLogLvl},       // wrong env flag
   100  		{nil, map[string]string{"MT_LOG_LEVEL": "debug"}, defaultLogLvl}, // wrong env prefix
   101  		{nil, map[string]string{"TM_LOG_LEVEL": "debug"}, "debug"},       // right env
   102  	}
   103  
   104  	for i, tc := range cases {
   105  		idxString := strconv.Itoa(i)
   106  
   107  		err := testSetup(defaultRoot, tc.args, tc.env)
   108  		require.Nil(t, err, idxString)
   109  
   110  		assert.Equal(t, tc.logLevel, config.LogLevel, idxString)
   111  	}
   112  }
   113  
   114  func TestRootConfig(t *testing.T) {
   115  	// write non-default config
   116  	nonDefaultLogLvl := "abc:debug"
   117  	cvals := map[string]string{
   118  		"log_level": nonDefaultLogLvl,
   119  	}
   120  
   121  	cases := []struct {
   122  		args []string
   123  		env  map[string]string
   124  
   125  		logLvl string
   126  	}{
   127  		{nil, nil, nonDefaultLogLvl},                                     // should load config
   128  		{[]string{"--log_level=abc:info"}, nil, "abc:info"},              // flag over rides
   129  		{nil, map[string]string{"TM_LOG_LEVEL": "abc:info"}, "abc:info"}, // env over rides
   130  	}
   131  
   132  	for i, tc := range cases {
   133  		idxString := strconv.Itoa(i)
   134  		clearConfig(defaultRoot)
   135  
   136  		// XXX: path must match cfg.defaultConfigPath
   137  		configFilePath := filepath.Join(defaultRoot, "config")
   138  		err := tmos.EnsureDir(configFilePath, 0o700)
   139  		require.Nil(t, err)
   140  
   141  		// write the non-defaults to a different path
   142  		// TODO: support writing sub configs so we can test that too
   143  		err = WriteConfigVals(configFilePath, cvals)
   144  		require.Nil(t, err)
   145  
   146  		rootCmd := testRootCmd()
   147  		cmd := cli.PrepareBaseCmd(rootCmd, "TM", defaultRoot)
   148  
   149  		// run with the args and env
   150  		tc.args = append([]string{rootCmd.Use}, tc.args...)
   151  		err = cli.RunWithArgs(cmd, tc.args, tc.env)
   152  		require.Nil(t, err, idxString)
   153  
   154  		assert.Equal(t, tc.logLvl, config.LogLevel, idxString)
   155  	}
   156  }
   157  
   158  // WriteConfigVals writes a toml file with the given values.
   159  // It returns an error if writing was impossible.
   160  func WriteConfigVals(dir string, vals map[string]string) error {
   161  	data := ""
   162  	for k, v := range vals {
   163  		data += fmt.Sprintf("%s = \"%s\"\n", k, v)
   164  	}
   165  	cfile := filepath.Join(dir, "config.toml")
   166  	return os.WriteFile(cfile, []byte(data), 0o600)
   167  }