Skip to content
New issue

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

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

Already on GitHub? # to your account

Add cli tests for auth #6152

Merged
merged 9 commits into from
May 6, 2020
12 changes: 0 additions & 12 deletions tests/cli/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,18 +167,6 @@ func (f *Fixtures) CLIConfig(key, value string, flags ...string) {
ExecuteWriteCheckErr(f.T, AddFlags(cmd, flags))
}

// TxBroadcast is simcli tx broadcast
func (f *Fixtures) TxBroadcast(fileName string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx broadcast %v %v", f.SimcliBinary, f.Flags(), fileName)
return ExecuteWriteRetStdStreams(f.T, AddFlags(cmd, flags), clientkeys.DefaultKeyPass)
}

// TxEncode is simcli tx encode
func (f *Fixtures) TxEncode(fileName string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx encode %v %v", f.SimcliBinary, f.Flags(), fileName)
return ExecuteWriteRetStdStreams(f.T, AddFlags(cmd, flags), clientkeys.DefaultKeyPass)
}

//utils

func AddFlags(cmd string, flags []string) string {
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/simd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func TestCLIValidateGenesis(t *testing.T) {

// start simd server
proc := f.SDStart()
defer proc.Stop(false)
t.Cleanup(func() { proc.Stop(false) })

f.ValidateGenesis()

Expand Down
334 changes: 333 additions & 1 deletion x/auth/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
package cli_test

import (
"encoding/base64"
"fmt"
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/cosmos/cosmos-sdk/tests/cli"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/testutil"
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
)

func TestCLIValidateSignatures(t *testing.T) {
Expand All @@ -27,7 +33,7 @@ func TestCLIValidateSignatures(t *testing.T) {
barAddr := f.KeyAddress(cli.KeyBar)

// generate sendTx with default gas
success, stdout, stderr := testutil.TxSend(f, fooAddr.String(), barAddr, sdk.NewInt64Coin("stake", 10), "--generate-only")
success, stdout, stderr := bankcli.TxSend(f, fooAddr.String(), barAddr, sdk.NewInt64Coin("stake", 10), "--generate-only")
require.True(t, success)
require.Empty(t, stderr)

Expand Down Expand Up @@ -66,3 +72,329 @@ func TestCLIValidateSignatures(t *testing.T) {
// Cleanup testing directories
f.Cleanup()
}

func TestCLISendGenerateSignAndBroadcast(t *testing.T) {
t.Parallel()
f := cli.InitFixtures(t)

// start simd server
proc := f.SDStart()
t.Cleanup(func() { proc.Stop(false) })

fooAddr := f.KeyAddress(cli.KeyFoo)
barAddr := f.KeyAddress(cli.KeyBar)

// Test generate sendTx with default gas
sendTokens := sdk.TokensFromConsensusPower(10)
success, stdout, stderr := bankcli.TxSend(f, fooAddr.String(), barAddr, sdk.NewCoin(cli.Denom, sendTokens), "--generate-only")
require.True(t, success)
require.Empty(t, stderr)
msg := cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.Equal(t, msg.Fee.Gas, uint64(flags.DefaultGasLimit))
require.Equal(t, len(msg.Msgs), 1)
require.Equal(t, 0, len(msg.GetSignatures()))

// Test generate sendTx with --gas=$amount
success, stdout, stderr = bankcli.TxSend(f, fooAddr.String(), barAddr, sdk.NewCoin(cli.Denom, sendTokens), "--gas=100", "--generate-only")
require.True(t, success)
require.Empty(t, stderr)

msg = cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.Equal(t, msg.Fee.Gas, uint64(100))
require.Equal(t, len(msg.Msgs), 1)
require.Equal(t, 0, len(msg.GetSignatures()))

// Test generate sendTx, estimate gas
success, stdout, stderr = bankcli.TxSend(f, fooAddr.String(), barAddr, sdk.NewCoin(cli.Denom, sendTokens), "--generate-only")
require.True(t, success)
require.Empty(t, stderr)
msg = cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.True(t, msg.Fee.Gas > 0)
require.Equal(t, len(msg.Msgs), 1)

// Write the output to disk
unsignedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Test validate-signatures
success, stdout, _ = testutil.TxValidateSignatures(f, unsignedTxFile.Name())
require.False(t, success)
require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", fooAddr.String()), stdout)

// Test sign

// Does not work in offline mode
success, stdout, stderr = testutil.TxSign(f, cli.KeyFoo, unsignedTxFile.Name(), "--offline")
require.Contains(t, stderr, "required flag(s) \"account-number\", \"sequence\" not set")
require.False(t, success)

// But works offline if we set account number and sequence
success, _, _ = testutil.TxSign(f, cli.KeyFoo, unsignedTxFile.Name(), "--offline", "--account-number", "1", "--sequence", "1")
require.True(t, success)

// Sign transaction
success, stdout, _ = testutil.TxSign(f, cli.KeyFoo, unsignedTxFile.Name())
require.True(t, success)
msg = cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.Equal(t, len(msg.Msgs), 1)
require.Equal(t, 1, len(msg.GetSignatures()))
require.Equal(t, fooAddr.String(), msg.GetSigners()[0].String())

// Write the output to disk
signedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Test validate-signatures
success, stdout, _ = testutil.TxValidateSignatures(f, signedTxFile.Name())
require.True(t, success)
require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n 0: %v\t\t\t[OK]\n\n", fooAddr.String(),
fooAddr.String()), stdout)

// Ensure foo has right amount of funds
startTokens := sdk.TokensFromConsensusPower(50)
require.Equal(t, startTokens, bankcli.QueryBalances(f, fooAddr).AmountOf(cli.Denom))

// Test broadcast

// Does not work in offline mode
success, _, stderr = testutil.TxBroadcast(f, signedTxFile.Name(), "--offline")
require.Contains(t, stderr, "cannot broadcast tx during offline mode")
require.False(t, success)
tests.WaitForNextNBlocksTM(1, f.Port)

success, stdout, _ = testutil.TxBroadcast(f, signedTxFile.Name())
require.True(t, success)
tests.WaitForNextNBlocksTM(1, f.Port)

// Ensure account state
require.Equal(t, sendTokens, bankcli.QueryBalances(f, barAddr).AmountOf(cli.Denom))
require.Equal(t, startTokens.Sub(sendTokens), bankcli.QueryBalances(f, fooAddr).AmountOf(cli.Denom))

f.Cleanup()
}

func TestCLIMultisignInsufficientCosigners(t *testing.T) {
t.Parallel()
f := cli.InitFixtures(t)

// start simd server with minimum fees
proc := f.SDStart()
t.Cleanup(func() { proc.Stop(false) })

fooBarBazAddr := f.KeyAddress(cli.KeyFooBarBaz)
barAddr := f.KeyAddress(cli.KeyBar)

// Send some tokens from one account to the other
success, _, _ := bankcli.TxSend(f, cli.KeyFoo, fooBarBazAddr, sdk.NewInt64Coin(cli.Denom, 10), "-y")
require.True(t, success)
tests.WaitForNextNBlocksTM(1, f.Port)

// Test generate sendTx with multisig
success, stdout, _ := bankcli.TxSend(f, fooBarBazAddr.String(), barAddr, sdk.NewInt64Coin(cli.Denom, 5), "--generate-only")
require.True(t, success)

// Write the output to disk
unsignedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Sign with foo's key
success, stdout, _ = testutil.TxSign(f, cli.KeyFoo, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String(), "-y")
require.True(t, success)

// Write the output to disk
fooSignatureFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Multisign, not enough signatures
success, stdout, _ = testutil.TxMultisign(f, unsignedTxFile.Name(), cli.KeyFooBarBaz, []string{fooSignatureFile.Name()})
require.True(t, success)

// Write the output to disk
signedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Validate the multisignature
success, _, _ = testutil.TxValidateSignatures(f, signedTxFile.Name())
require.False(t, success)

// Broadcast the transaction
success, stdOut, _ := testutil.TxBroadcast(f, signedTxFile.Name())
require.Contains(t, stdOut, "signature verification failed")
require.True(t, success)

// Cleanup testing directories
f.Cleanup()
}

func TestCLIEncode(t *testing.T) {
t.Parallel()
f := cli.InitFixtures(t)

// start simd server
proc := f.SDStart()
t.Cleanup(func() { proc.Stop(false) })

// Build a testing transaction and write it to disk
barAddr := f.KeyAddress(cli.KeyBar)
keyAddr := f.KeyAddress(cli.KeyFoo)

sendTokens := sdk.TokensFromConsensusPower(10)
success, stdout, stderr := bankcli.TxSend(f, keyAddr.String(), barAddr, sdk.NewCoin(cli.Denom, sendTokens), "--generate-only", "--memo", "deadbeef")
require.True(t, success)
require.Empty(t, stderr)

// Write it to disk
jsonTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Run the encode command, and trim the extras from the stdout capture
success, base64Encoded, _ := testutil.TxEncode(f, jsonTxFile.Name())
require.True(t, success)
trimmedBase64 := strings.Trim(base64Encoded, "\"\n")

// Decode the base64
decodedBytes, err := base64.StdEncoding.DecodeString(trimmedBase64)
require.Nil(t, err)

// Check that the transaction decodes as epxceted
var decodedTx auth.StdTx
require.Nil(t, f.Cdc.UnmarshalBinaryBare(decodedBytes, &decodedTx))
require.Equal(t, "deadbeef", decodedTx.Memo)
}

func TestCLIMultisignSortSignatures(t *testing.T) {
t.Parallel()
f := cli.InitFixtures(t)

// start simd server with minimum fees
proc := f.SDStart()
t.Cleanup(func() { proc.Stop(false) })

fooBarBazAddr := f.KeyAddress(cli.KeyFooBarBaz)
barAddr := f.KeyAddress(cli.KeyBar)

// Send some tokens from one account to the other
success, _, _ := bankcli.TxSend(f, cli.KeyFoo, fooBarBazAddr, sdk.NewInt64Coin(cli.Denom, 10), "-y")
require.True(t, success)
tests.WaitForNextNBlocksTM(1, f.Port)

// Ensure account balances match expected
require.Equal(t, int64(10), bankcli.QueryBalances(f, fooBarBazAddr).AmountOf(cli.Denom).Int64())

// Test generate sendTx with multisig
success, stdout, _ := bankcli.TxSend(f, fooBarBazAddr.String(), barAddr, sdk.NewInt64Coin(cli.Denom, 5), "--generate-only")
require.True(t, success)

// Write the output to disk
unsignedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Sign with foo's key
success, stdout, _ = testutil.TxSign(f, cli.KeyFoo, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String())
require.True(t, success)

// Write the output to disk
fooSignatureFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Sign with baz's key
success, stdout, _ = testutil.TxSign(f, cli.KeyBaz, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String())
require.True(t, success)

// Write the output to disk
bazSignatureFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Multisign, keys in different order
success, stdout, _ = testutil.TxMultisign(f, unsignedTxFile.Name(), cli.KeyFooBarBaz, []string{
bazSignatureFile.Name(), fooSignatureFile.Name()})
require.True(t, success)

// Write the output to disk
signedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Validate the multisignature
success, _, _ = testutil.TxValidateSignatures(f, signedTxFile.Name())
require.True(t, success)

// Broadcast the transaction
success, _, _ = testutil.TxBroadcast(f, signedTxFile.Name())
require.True(t, success)

// Cleanup testing directories
f.Cleanup()
}

func TestCLIMultisign(t *testing.T) {
t.Parallel()
f := cli.InitFixtures(t)

// start simd server with minimum fees
proc := f.SDStart()
t.Cleanup(func() { proc.Stop(false) })

fooBarBazAddr := f.KeyAddress(cli.KeyFooBarBaz)
bazAddr := f.KeyAddress(cli.KeyBaz)

// Send some tokens from one account to the other
success, _, _ := bankcli.TxSend(f, cli.KeyFoo, fooBarBazAddr, sdk.NewInt64Coin(cli.Denom, 10), "-y")
require.True(t, success)
tests.WaitForNextNBlocksTM(1, f.Port)

// Ensure account balances match expected
require.Equal(t, int64(10), bankcli.QueryBalances(f, fooBarBazAddr).AmountOf(cli.Denom).Int64())

// Test generate sendTx with multisig
success, stdout, stderr := bankcli.TxSend(f, fooBarBazAddr.String(), bazAddr, sdk.NewInt64Coin(cli.Denom, 10), "--generate-only")
require.True(t, success)
require.Empty(t, stderr)

// Write the output to disk
unsignedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Sign with foo's key
success, stdout, _ = testutil.TxSign(f, cli.KeyFoo, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String(), "-y")
require.True(t, success)

// Write the output to disk
fooSignatureFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Sign with bar's key
success, stdout, _ = testutil.TxSign(f, cli.KeyBar, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String(), "-y")
require.True(t, success)

// Write the output to disk
barSignatureFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Multisign

// Does not work in offline mode
success, stdout, _ = testutil.TxMultisign(f, unsignedTxFile.Name(), cli.KeyFooBarBaz, []string{
fooSignatureFile.Name(), barSignatureFile.Name()}, "--offline")
require.Contains(t, "couldn't verify signature", stdout)
require.False(t, success)

// Success multisign
success, stdout, _ = testutil.TxMultisign(f, unsignedTxFile.Name(), cli.KeyFooBarBaz, []string{
fooSignatureFile.Name(), barSignatureFile.Name()})
require.True(t, success)

// Write the output to disk
signedTxFile, cleanup := tests.WriteToNewTempFile(t, stdout)
t.Cleanup(cleanup)

// Validate the multisignature
success, _, _ = testutil.TxValidateSignatures(f, signedTxFile.Name())
require.True(t, success)

// Broadcast the transaction
success, _, _ = testutil.TxBroadcast(f, signedTxFile.Name())
require.True(t, success)

// Cleanup testing directories
f.Cleanup()
}
Loading