github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/cmd/tendermint/commands/root_test.go (about)

     1  package commands
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     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/ari-anchor/sei-tendermint/config"
    16  	"github.com/ari-anchor/sei-tendermint/libs/cli"
    17  	"github.com/ari-anchor/sei-tendermint/libs/log"
    18  	tmos "github.com/ari-anchor/sei-tendermint/libs/os"
    19  )
    20  
    21  // writeConfigVals writes a toml file with the given values.
    22  // It returns an error if writing was impossible.
    23  func writeConfigVals(dir string, vals map[string]string) error {
    24  	data := ""
    25  	for k, v := range vals {
    26  		data += fmt.Sprintf("%s = \"%s\"\n", k, v)
    27  	}
    28  	cfile := filepath.Join(dir, "config.toml")
    29  	return os.WriteFile(cfile, []byte(data), 0600)
    30  }
    31  
    32  // clearConfig clears env vars, the given root dir, and resets viper.
    33  func clearConfig(t *testing.T, dir string) *cfg.Config {
    34  	t.Helper()
    35  	require.NoError(t, os.Unsetenv("TMHOME"))
    36  	require.NoError(t, os.Unsetenv("TM_HOME"))
    37  	require.NoError(t, os.RemoveAll(dir))
    38  
    39  	viper.Reset()
    40  	conf := cfg.DefaultConfig()
    41  	conf.RootDir = dir
    42  	return conf
    43  }
    44  
    45  // prepare new rootCmd
    46  func testRootCmd(conf *cfg.Config) *cobra.Command {
    47  	logger := log.NewNopLogger()
    48  	cmd := RootCommand(conf, logger)
    49  	cmd.RunE = func(cmd *cobra.Command, args []string) error { return nil }
    50  
    51  	var l string
    52  	cmd.PersistentFlags().String("log", l, "Log")
    53  	return cmd
    54  }
    55  
    56  func testSetup(ctx context.Context, t *testing.T, conf *cfg.Config, args []string, env map[string]string) error {
    57  	t.Helper()
    58  
    59  	cmd := testRootCmd(conf)
    60  	viper.Set(cli.HomeFlag, conf.RootDir)
    61  
    62  	// run with the args and env
    63  	args = append([]string{cmd.Use}, args...)
    64  	return cli.RunWithArgs(ctx, cmd, args, env)
    65  }
    66  
    67  func TestRootHome(t *testing.T) {
    68  	defaultRoot := t.TempDir()
    69  	newRoot := filepath.Join(defaultRoot, "something-else")
    70  	cases := []struct {
    71  		args []string
    72  		env  map[string]string
    73  		root string
    74  	}{
    75  		{nil, nil, defaultRoot},
    76  		{[]string{"--home", newRoot}, nil, newRoot},
    77  		{nil, map[string]string{"TMHOME": newRoot}, newRoot},
    78  	}
    79  
    80  	ctx, cancel := context.WithCancel(context.Background())
    81  	defer cancel()
    82  
    83  	for i, tc := range cases {
    84  		t.Run(fmt.Sprint(i), func(t *testing.T) {
    85  			conf := clearConfig(t, tc.root)
    86  
    87  			err := testSetup(ctx, t, conf, tc.args, tc.env)
    88  			require.NoError(t, err)
    89  
    90  			require.Equal(t, tc.root, conf.RootDir)
    91  			require.Equal(t, tc.root, conf.P2P.RootDir)
    92  			require.Equal(t, tc.root, conf.Consensus.RootDir)
    93  			require.Equal(t, tc.root, conf.Mempool.RootDir)
    94  		})
    95  	}
    96  }
    97  
    98  func TestRootFlagsEnv(t *testing.T) {
    99  	// defaults
   100  	defaults := cfg.DefaultConfig()
   101  	defaultDir := t.TempDir()
   102  
   103  	defaultLogLvl := defaults.LogLevel
   104  
   105  	cases := []struct {
   106  		args     []string
   107  		env      map[string]string
   108  		logLevel string
   109  	}{
   110  		{[]string{"--log", "debug"}, nil, defaultLogLvl},                 // wrong flag
   111  		{[]string{"--log-level", "debug"}, nil, "debug"},                 // right flag
   112  		{nil, map[string]string{"TM_LOW": "debug"}, defaultLogLvl},       // wrong env flag
   113  		{nil, map[string]string{"MT_LOG_LEVEL": "debug"}, defaultLogLvl}, // wrong env prefix
   114  		{nil, map[string]string{"TM_LOG_LEVEL": "debug"}, "debug"},       // right env
   115  	}
   116  
   117  	ctx, cancel := context.WithCancel(context.Background())
   118  	defer cancel()
   119  
   120  	for i, tc := range cases {
   121  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   122  			conf := clearConfig(t, defaultDir)
   123  
   124  			err := testSetup(ctx, t, conf, tc.args, tc.env)
   125  			require.NoError(t, err)
   126  
   127  			assert.Equal(t, tc.logLevel, conf.LogLevel)
   128  		})
   129  
   130  	}
   131  }
   132  
   133  func TestRootConfig(t *testing.T) {
   134  	ctx, cancel := context.WithCancel(context.Background())
   135  	defer cancel()
   136  
   137  	// write non-default config
   138  	nonDefaultLogLvl := "debug"
   139  	cvals := map[string]string{
   140  		"log-level": nonDefaultLogLvl,
   141  	}
   142  
   143  	cases := []struct {
   144  		args   []string
   145  		env    map[string]string
   146  		logLvl string
   147  	}{
   148  		{[]string{"--log-level=info"}, nil, "info"},              // flag over rides
   149  		{nil, map[string]string{"TM_LOG_LEVEL": "info"}, "info"}, // env over rides
   150  	}
   151  
   152  	for i, tc := range cases {
   153  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   154  			defaultRoot := t.TempDir()
   155  			conf := clearConfig(t, defaultRoot)
   156  			conf.LogLevel = tc.logLvl
   157  
   158  			// XXX: path must match cfg.defaultConfigPath
   159  			configFilePath := filepath.Join(defaultRoot, "config")
   160  			err := tmos.EnsureDir(configFilePath, 0700)
   161  			require.NoError(t, err)
   162  
   163  			// write the non-defaults to a different path
   164  			// TODO: support writing sub configs so we can test that too
   165  			err = writeConfigVals(configFilePath, cvals)
   166  			require.NoError(t, err)
   167  
   168  			cmd := testRootCmd(conf)
   169  
   170  			// run with the args and env
   171  			tc.args = append([]string{cmd.Use}, tc.args...)
   172  			err = cli.RunWithArgs(ctx, cmd, tc.args, tc.env)
   173  			require.NoError(t, err)
   174  
   175  			require.Equal(t, tc.logLvl, conf.LogLevel)
   176  		})
   177  	}
   178  }
   179  
   180  // WriteConfigVals writes a toml file with the given values.
   181  // It returns an error if writing was impossible.
   182  func WriteConfigVals(dir string, vals map[string]string) error {
   183  	data := ""
   184  	for k, v := range vals {
   185  		data += fmt.Sprintf("%s = \"%s\"\n", k, v)
   186  	}
   187  	cfile := filepath.Join(dir, "config.toml")
   188  	return os.WriteFile(cfile, []byte(data), 0600)
   189  }