github.com/cosmos/cosmos-sdk@v0.50.10/x/genutil/client/cli/init_test.go (about)

     1  package cli_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	abci_server "github.com/cometbft/cometbft/abci/server"
    13  	"github.com/spf13/viper"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"cosmossdk.io/log"
    17  
    18  	"github.com/cosmos/cosmos-sdk/client"
    19  	"github.com/cosmos/cosmos-sdk/client/flags"
    20  	"github.com/cosmos/cosmos-sdk/codec"
    21  	"github.com/cosmos/cosmos-sdk/codec/types"
    22  	cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
    23  	"github.com/cosmos/cosmos-sdk/server"
    24  	servercmtlog "github.com/cosmos/cosmos-sdk/server/log"
    25  	"github.com/cosmos/cosmos-sdk/server/mock"
    26  	"github.com/cosmos/cosmos-sdk/testutil"
    27  	"github.com/cosmos/cosmos-sdk/testutil/network"
    28  	sdk "github.com/cosmos/cosmos-sdk/types"
    29  	"github.com/cosmos/cosmos-sdk/types/module"
    30  	"github.com/cosmos/cosmos-sdk/x/genutil"
    31  	genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
    32  	genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil"
    33  	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
    34  	"github.com/cosmos/cosmos-sdk/x/staking"
    35  )
    36  
    37  var testMbm = module.NewBasicManager(
    38  	staking.AppModuleBasic{},
    39  	genutil.AppModuleBasic{},
    40  )
    41  
    42  func TestInitCmd(t *testing.T) {
    43  	tests := []struct {
    44  		name      string
    45  		flags     func(dir string) []string
    46  		shouldErr bool
    47  		err       error
    48  	}{
    49  		{
    50  			name: "happy path",
    51  			flags: func(dir string) []string {
    52  				return []string{
    53  					"appnode-test",
    54  				}
    55  			},
    56  			shouldErr: false,
    57  			err:       nil,
    58  		},
    59  	}
    60  
    61  	for _, tt := range tests {
    62  		tt := tt
    63  		t.Run(tt.name, func(t *testing.T) {
    64  			home := t.TempDir()
    65  			logger := log.NewNopLogger()
    66  			cfg, err := genutiltest.CreateDefaultCometConfig(home)
    67  			require.NoError(t, err)
    68  
    69  			serverCtx := server.NewContext(viper.New(), cfg, logger)
    70  			interfaceRegistry := types.NewInterfaceRegistry()
    71  			marshaler := codec.NewProtoCodec(interfaceRegistry)
    72  			clientCtx := client.Context{}.
    73  				WithCodec(marshaler).
    74  				WithLegacyAmino(makeCodec()).
    75  				WithHomeDir(home)
    76  
    77  			ctx := context.Background()
    78  			ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
    79  			ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
    80  
    81  			cmd := genutilcli.InitCmd(testMbm, home)
    82  			cmd.SetArgs(
    83  				tt.flags(home),
    84  			)
    85  
    86  			if tt.shouldErr {
    87  				err := cmd.ExecuteContext(ctx)
    88  				require.EqualError(t, err, tt.err.Error())
    89  			} else {
    90  				require.NoError(t, cmd.ExecuteContext(ctx))
    91  			}
    92  		})
    93  	}
    94  }
    95  
    96  func TestInitRecover(t *testing.T) {
    97  	home := t.TempDir()
    98  	logger := log.NewNopLogger()
    99  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   100  	require.NoError(t, err)
   101  
   102  	serverCtx := server.NewContext(viper.New(), cfg, logger)
   103  	interfaceRegistry := types.NewInterfaceRegistry()
   104  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   105  	clientCtx := client.Context{}.
   106  		WithCodec(marshaler).
   107  		WithLegacyAmino(makeCodec()).
   108  		WithHomeDir(home)
   109  
   110  	ctx := context.Background()
   111  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   112  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   113  
   114  	cmd := genutilcli.InitCmd(testMbm, home)
   115  	mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
   116  
   117  	cmd.SetArgs([]string{
   118  		"appnode-test",
   119  		fmt.Sprintf("--%s=true", genutilcli.FlagRecover),
   120  	})
   121  
   122  	// use valid mnemonic and complete recovery key generation successfully
   123  	mockIn.Reset("decide praise business actor peasant farm drastic weather extend front hurt later song give verb rhythm worry fun pond reform school tumble august one\n")
   124  	require.NoError(t, cmd.ExecuteContext(ctx))
   125  }
   126  
   127  func TestInitDefaultBondDenom(t *testing.T) {
   128  	home := t.TempDir()
   129  	logger := log.NewNopLogger()
   130  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   131  	require.NoError(t, err)
   132  
   133  	serverCtx := server.NewContext(viper.New(), cfg, logger)
   134  	interfaceRegistry := types.NewInterfaceRegistry()
   135  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   136  	clientCtx := client.Context{}.
   137  		WithCodec(marshaler).
   138  		WithLegacyAmino(makeCodec()).
   139  		WithHomeDir(home)
   140  
   141  	ctx := context.Background()
   142  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   143  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   144  
   145  	cmd := genutilcli.InitCmd(testMbm, home)
   146  
   147  	cmd.SetArgs([]string{
   148  		"appnode-test",
   149  		fmt.Sprintf("--%s=%s", flags.FlagHome, home),
   150  		fmt.Sprintf("--%s=testtoken", genutilcli.FlagDefaultBondDenom),
   151  	})
   152  	require.NoError(t, cmd.ExecuteContext(ctx))
   153  }
   154  
   155  func TestEmptyState(t *testing.T) {
   156  	home := t.TempDir()
   157  	logger := log.NewNopLogger()
   158  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   159  	require.NoError(t, err)
   160  
   161  	serverCtx := server.NewContext(viper.New(), cfg, logger)
   162  	interfaceRegistry := types.NewInterfaceRegistry()
   163  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   164  	clientCtx := client.Context{}.
   165  		WithCodec(marshaler).
   166  		WithLegacyAmino(makeCodec()).
   167  		WithHomeDir(home)
   168  
   169  	ctx := context.Background()
   170  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   171  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   172  
   173  	cmd := genutilcli.InitCmd(testMbm, home)
   174  	cmd.SetArgs([]string{"appnode-test", fmt.Sprintf("--%s=%s", flags.FlagHome, home)})
   175  
   176  	require.NoError(t, cmd.ExecuteContext(ctx))
   177  
   178  	old := os.Stdout
   179  	r, w, _ := os.Pipe()
   180  	os.Stdout = w
   181  
   182  	cmd = server.ExportCmd(nil, home)
   183  	cmd.SetArgs([]string{fmt.Sprintf("--%s=%s", flags.FlagHome, home)})
   184  	require.NoError(t, cmd.ExecuteContext(ctx))
   185  
   186  	outC := make(chan string)
   187  	go func() {
   188  		var buf bytes.Buffer
   189  		io.Copy(&buf, r)
   190  		outC <- buf.String()
   191  	}()
   192  
   193  	w.Close()
   194  	os.Stdout = old
   195  	out := <-outC
   196  
   197  	require.Contains(t, out, "genesis_time")
   198  	require.Contains(t, out, "chain_id")
   199  	require.Contains(t, out, "consensus")
   200  	require.Contains(t, out, "app_hash")
   201  	require.Contains(t, out, "app_state")
   202  }
   203  
   204  func TestStartStandAlone(t *testing.T) {
   205  	home := t.TempDir()
   206  	logger := log.NewNopLogger()
   207  	interfaceRegistry := types.NewInterfaceRegistry()
   208  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   209  	err := genutiltest.ExecInitCmd(testMbm, home, marshaler)
   210  	require.NoError(t, err)
   211  
   212  	app, err := mock.NewApp(home, logger)
   213  	require.NoError(t, err)
   214  
   215  	svrAddr, _, closeFn, err := network.FreeTCPAddr()
   216  	require.NoError(t, err)
   217  	require.NoError(t, closeFn())
   218  
   219  	cmtApp := server.NewCometABCIWrapper(app)
   220  	svr, err := abci_server.NewServer(svrAddr, "socket", cmtApp)
   221  	require.NoError(t, err, "error creating listener")
   222  
   223  	svr.SetLogger(servercmtlog.CometLoggerWrapper{Logger: logger.With("module", "abci-server")})
   224  	err = svr.Start()
   225  	require.NoError(t, err)
   226  
   227  	timer := time.NewTimer(time.Duration(2) * time.Second)
   228  	for range timer.C {
   229  		err = svr.Stop()
   230  		require.NoError(t, err)
   231  		break
   232  	}
   233  }
   234  
   235  func TestInitNodeValidatorFiles(t *testing.T) {
   236  	home := t.TempDir()
   237  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   238  	require.NoError(t, err)
   239  
   240  	nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(cfg)
   241  	require.NoError(t, err)
   242  
   243  	require.NotEqual(t, "", nodeID)
   244  	require.NotEqual(t, 0, len(valPubKey.Bytes()))
   245  }
   246  
   247  func TestInitConfig(t *testing.T) {
   248  	home := t.TempDir()
   249  	logger := log.NewNopLogger()
   250  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   251  	require.NoError(t, err)
   252  
   253  	serverCtx := server.NewContext(viper.New(), cfg, logger)
   254  	interfaceRegistry := types.NewInterfaceRegistry()
   255  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   256  	clientCtx := client.Context{}.
   257  		WithCodec(marshaler).
   258  		WithLegacyAmino(makeCodec()).
   259  		WithChainID("foo"). // add chain-id to clientCtx
   260  		WithHomeDir(home)
   261  
   262  	ctx := context.Background()
   263  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   264  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   265  
   266  	cmd := genutilcli.InitCmd(testMbm, home)
   267  	cmd.SetArgs([]string{"testnode"})
   268  
   269  	require.NoError(t, cmd.ExecuteContext(ctx))
   270  
   271  	old := os.Stdout
   272  	r, w, _ := os.Pipe()
   273  	os.Stdout = w
   274  
   275  	cmd = server.ExportCmd(nil, home)
   276  	require.NoError(t, cmd.ExecuteContext(ctx))
   277  
   278  	outC := make(chan string)
   279  	go func() {
   280  		var buf bytes.Buffer
   281  		io.Copy(&buf, r)
   282  		outC <- buf.String()
   283  	}()
   284  
   285  	w.Close()
   286  	os.Stdout = old
   287  	out := <-outC
   288  
   289  	require.Contains(t, out, "\"chain_id\": \"foo\"")
   290  }
   291  
   292  func TestInitWithHeight(t *testing.T) {
   293  	home := t.TempDir()
   294  	logger := log.NewNopLogger()
   295  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   296  	require.NoError(t, err)
   297  
   298  	serverCtx := server.NewContext(viper.New(), cfg, logger)
   299  	interfaceRegistry := types.NewInterfaceRegistry()
   300  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   301  	clientCtx := client.Context{}.
   302  		WithCodec(marshaler).
   303  		WithLegacyAmino(makeCodec()).
   304  		WithChainID("foo"). // add chain-id to clientCtx
   305  		WithHomeDir(home)
   306  
   307  	ctx := context.Background()
   308  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   309  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   310  
   311  	testInitialHeight := int64(333)
   312  
   313  	cmd := genutilcli.InitCmd(testMbm, home)
   314  	cmd.SetArgs([]string{"init-height-test", fmt.Sprintf("--%s=%d", flags.FlagInitHeight, testInitialHeight)})
   315  
   316  	require.NoError(t, cmd.ExecuteContext(ctx))
   317  
   318  	appGenesis, importErr := genutiltypes.AppGenesisFromFile(cfg.GenesisFile())
   319  	require.NoError(t, importErr)
   320  
   321  	require.Equal(t, testInitialHeight, appGenesis.InitialHeight)
   322  }
   323  
   324  func TestInitWithNegativeHeight(t *testing.T) {
   325  	home := t.TempDir()
   326  	logger := log.NewNopLogger()
   327  	cfg, err := genutiltest.CreateDefaultCometConfig(home)
   328  	require.NoError(t, err)
   329  
   330  	serverCtx := server.NewContext(viper.New(), cfg, logger)
   331  	interfaceRegistry := types.NewInterfaceRegistry()
   332  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   333  	clientCtx := client.Context{}.
   334  		WithCodec(marshaler).
   335  		WithLegacyAmino(makeCodec()).
   336  		WithChainID("foo"). // add chain-id to clientCtx
   337  		WithHomeDir(home)
   338  
   339  	ctx := context.Background()
   340  	ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
   341  	ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
   342  
   343  	testInitialHeight := int64(-333)
   344  
   345  	cmd := genutilcli.InitCmd(testMbm, home)
   346  	cmd.SetArgs([]string{"init-height-test", fmt.Sprintf("--%s=%d", flags.FlagInitHeight, testInitialHeight)})
   347  
   348  	require.NoError(t, cmd.ExecuteContext(ctx))
   349  
   350  	appGenesis, importErr := genutiltypes.AppGenesisFromFile(cfg.GenesisFile())
   351  	require.NoError(t, importErr)
   352  
   353  	require.Equal(t, int64(1), appGenesis.InitialHeight)
   354  }
   355  
   356  // custom tx codec
   357  func makeCodec() *codec.LegacyAmino {
   358  	cdc := codec.NewLegacyAmino()
   359  	sdk.RegisterLegacyAminoCodec(cdc)
   360  	cryptocodec.RegisterCrypto(cdc)
   361  	return cdc
   362  }