Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add env variable to cmd flags #9040

Merged
merged 12 commits into from
Apr 13, 2021
107 changes: 107 additions & 0 deletions client/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package config_test

import (
"bytes"
"fmt"
"io/ioutil"
"os"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/flags"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
)

const (
nodeEnv = "NODE"
testNode1 = "http://localhost:1"
testNode2 = "http://localhost:2"
)

// initClientContext initiates client Context for tests
func initClientContext(t *testing.T, envVar string) (client.Context, func()) {
home := t.TempDir()
clientCtx := client.Context{}.
WithHomeDir(home).
WithViper("")

clientCtx.Viper.BindEnv(nodeEnv)
cyberbono3 marked this conversation as resolved.
Show resolved Hide resolved
if envVar != "" {
os.Setenv(nodeEnv, envVar)
}

clientCtx, err := config.ReadFromClientConfig(clientCtx)
require.NoError(t, err)

return clientCtx, func() { _ = os.RemoveAll(home) }
}

func TestConfigCmd(t *testing.T) {
clientCtx, cleanup := initClientContext(t, testNode1)
defer func() {
os.Unsetenv(nodeEnv)
cleanup()
}()

// NODE=http://localhost:1 ./build/simd config node http://localhost:2
cmd := config.Cmd()
args := []string{"node", testNode2}
_, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
require.NoError(t, err)

//./build/simd config node //http://localhost:1
b := bytes.NewBufferString("")
cmd.SetOut(b)
cmd.SetArgs([]string{"node"})
cmd.Execute()
out, err := ioutil.ReadAll(b)
require.NoError(t, err)
require.Equal(t, string(out), testNode1+"\n")
}

func TestConfigCmdEnvFlag(t *testing.T) {
const (
defaultNode = "http://localhost:26657"
)

tt := []struct {
name string
envVar string
args []string
expNode string
}{
{"env var is set with no flag", testNode1, []string{"validators"}, testNode1},
{"env var is set with a flag", testNode1, []string{"validators", fmt.Sprintf("--%s=%s", flags.FlagNode, testNode2)}, testNode2},
{"env var is not set with no flag", "", []string{"validators"}, defaultNode},
{"env var is not set with a flag", "", []string{"validators", fmt.Sprintf("--%s=%s", flags.FlagNode, testNode2)}, testNode2},
}

for _, tc := range tt {
tc := tc
t.Run(tc.name, func(t *testing.T) {
clientCtx, cleanup := initClientContext(t, tc.envVar)
defer func() {
if tc.envVar != "" {
os.Unsetenv(nodeEnv)
}
cleanup()
}()
/*
env var is set with a flag

NODE=http://localhost:1 ./build/simd q staking validators --node http://localhost:2
Error: post failed: Post "http://localhost:2": dial tcp 127.0.0.1:2: connect: connection refused

We dial http://localhost:2 cause a flag has the higher priority than env variable.
*/
cmd := cli.GetQueryCmd()
_, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
require.Error(t, err)
require.Contains(t, err.Error(), tc.expNode, "Output does not contain expected Node")
})
}
}
4 changes: 3 additions & 1 deletion client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,10 @@ func (ctx Context) WithInterfaceRegistry(interfaceRegistry codectypes.InterfaceR

// WithViper returns the context with Viper field. This Viper instance is used to read
// client-side config from the config file.
func (ctx Context) WithViper() Context {
func (ctx Context) WithViper(prefix string) Context {
v := viper.New()
v.SetEnvPrefix(prefix)
v.AutomaticEnv()
ctx.Viper = v
return ctx
}
Expand Down
2 changes: 1 addition & 1 deletion simapp/simd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
WithAccountRetriever(types.AccountRetriever{}).
WithBroadcastMode(flags.BroadcastBlock).
WithHomeDir(simapp.DefaultNodeHome).
WithViper()
WithViper("") // In simapp, we don't use any prefix for env variables.

rootCmd := &cobra.Command{
Use: "simd",
Expand Down