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 }