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

test: migrate e2e/tx tests to systemtest #22152

Merged
merged 20 commits into from
Oct 24, 2024
Merged

test: migrate e2e/tx tests to systemtest #22152

merged 20 commits into from
Oct 24, 2024

Conversation

hieuvubk
Copy link
Contributor

@hieuvubk hieuvubk commented Oct 7, 2024

Description

Closes: #22038

Migrate e2e/tx/service_test.go to systemtest.

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

Please see Pull Request Reviewer section in the contributing guide for more information on how to review a pull request.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

  • New Features

    • Introduced a new JSON file for transaction representation in the Cosmos SDK format.
    • Added a comprehensive suite of tests for transaction functionalities, including querying, simulating, and encoding/decoding transactions.
  • Bug Fixes

    • Removed outdated end-to-end tests that were previously validating transaction services.
  • Chores

    • Cleaned up test data by deleting obsolete test files.

Copy link
Contributor

coderabbitai bot commented Oct 7, 2024

📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes involve the deletion of an end-to-end test suite for transaction services located in tests/e2e/tx/service_test.go and its associated test data file tests/e2e/tx/testdata/tx_amino1.json. In their place, a new comprehensive suite of system tests has been introduced in tests/systemtests/tx_test.go, which covers various transaction functionalities including querying, simulating, encoding, and decoding transactions. A new transaction data file tests/systemtests/testdata/tx_amino1.json has also been added to support these tests.

Changes

File(s) Change Summary
tests/e2e/tx/service_test.go Deleted file containing end-to-end test suite for transaction services.
tests/e2e/tx/testdata/tx_amino1.json Deleted file containing JSON representation of a transaction in Cosmos SDK format.
tests/systemtests/testdata/tx_amino1.json New JSON file added representing a transaction in Cosmos SDK format.
tests/systemtests/tx_test.go Added comprehensive suite of system tests for transaction functionalities, including multiple test functions.

Assessment against linked issues

Objective Addressed Explanation
Migrate end-to-end tests to system tests (#22038)
Verify tests run with v1 and v2 (#22038)
Delete old end-to-end test (#22038)

Possibly related PRs

Suggested reviewers

  • alpe
  • julienrbrt
  • tac0turtle
  • testinginprod

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@hieuvubk hieuvubk marked this pull request as ready for review October 21, 2024 13:05
@hieuvubk hieuvubk requested a review from a team as a code owner October 21, 2024 13:05
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (2)
tests/systemtests/genesis_io.go (1)

60-70: LGTM: Well-implemented helper function with a minor suggestion.

The StoreTempFile function is well-implemented and follows best practices:

  • It's correctly marked as a helper function with t.Helper().
  • Error handling is appropriately done using require.NoError.
  • The file is properly closed before returning.

Consider adding a comment to explain that the file is closed before returning, as this might not be immediately obvious to all readers:

// StoreTempFile creates a temporary file in the test's temporary directory with the provided content.
// It returns a pointer to the created file. The file is closed before returning.
// Errors during the process are handled with test assertions.
func StoreTempFile(t *testing.T, content []byte) *os.File {
    // ... (existing implementation)
}
tests/systemtests/tx_test.go (1)

1077-1081: Use consistent paths for keyring home directories

The --home flag paths in commands should be consistent. In lines 1077 and 1079, the paths are --home=./testnet, whereas in other places like line 160, --home=./testnet/node0/simd is used. Ensure that the paths point to the correct directories and consider defining a variable for the home path to avoid confusion.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6e59ad0 and c097fe5.

⛔ Files ignored due to path filters (1)
  • tests/systemtests/testdata/tx_amino1.bin is excluded by !**/*.bin
📒 Files selected for processing (5)
  • tests/e2e/tx/service_test.go (0 hunks)
  • tests/e2e/tx/testdata/tx_amino1.json (0 hunks)
  • tests/systemtests/genesis_io.go (2 hunks)
  • tests/systemtests/testdata/tx_amino1.json (1 hunks)
  • tests/systemtests/tx_test.go (1 hunks)
💤 Files with no reviewable changes (2)
  • tests/e2e/tx/service_test.go
  • tests/e2e/tx/testdata/tx_amino1.json
✅ Files skipped from review due to trivial changes (1)
  • tests/systemtests/testdata/tx_amino1.json
🧰 Additional context used
📓 Path-based instructions (2)
tests/systemtests/genesis_io.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"

tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (1)
tests/systemtests/genesis_io.go (1)

4-7: LGTM: New imports are correctly placed and necessary.

The new imports for "bytes", "io", and "os" are correctly placed and are required for the newly added StoreTempFile function. This adheres to the Uber Golang style guide.

Comment on lines 73 to 135
func TestSimulateTx_GRPC(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
receiverAddr := cli.AddKey("account1")
denom := "stake"
var transferAmount int64 = 1000

sut.StartChain(t)

qc := tx.NewServiceClient(sut.RPCClient(t))

// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
require.NoError(t, err)

testCases := []struct {
name string
req *tx.SimulateRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.SimulateRequest{}, true, "empty txBytes is not allowed"},
{"valid request with tx_bytes", &tx.SimulateRequest{TxBytes: txBz}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Broadcast the tx via gRPC via the validator's clientCtx (which goes
// through Tendermint).
res, err := qc.Simulate(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
// Check the result and gas used are correct.
//
// The 12 events are:
// - Sending Fee to the pool: coin_spent, coin_received and transfer
// - tx.* events: tx.fee, tx.acc_seq, tx.signature
// - Sending Amount to recipient: coin_spent, coin_received and transfer
// - Msg events: message.module=bank, message.action=/cosmos.bank.v1beta1.MsgSend and message.sender=<val1> (in one message)
require.Equal(t, 10, len(res.GetResult().GetEvents()))
require.True(t, res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty.
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in TestSimulateTx_GRPC and TestSimulateTx_GRPCGateway

The functions TestSimulateTx_GRPC (lines 73-135) and TestSimulateTx_GRPCGateway (lines 137-199) contain duplicated code. Consider refactoring the common setup and logic into helper functions to improve maintainability and reduce redundancy.

Also applies to: 137-199

Comment on lines 201 to 317
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)

rsp = cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake")
txResult, found = cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)

testCases := []struct {
name string
req *tx.GetTxsEventRequest
expErr bool
expErrMsg string
expLen int
}{
{
"nil request",
nil,
true,
"request cannot be nil",
0,
},
{
"empty request",
&tx.GetTxsEventRequest{},
true,
"query cannot be empty",
0,
},
{
"request with dummy event",
&tx.GetTxsEventRequest{Query: "foobar"},
true,
"failed to search for txs",
0,
},
{
"request with order-by",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
OrderBy: tx.OrderBy_ORDER_BY_ASC,
},
false,
"",
2,
},
{
"without pagination",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
},
false,
"",
2,
},
{
"with pagination",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
Page: 1,
Limit: 1,
},
false,
"",
1,
},
{
"with multi events",
&tx.GetTxsEventRequest{
Query: fmt.Sprintf("%s AND message.module='bank'", bankMsgSendEventAction),
},
false,
"",
2,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Query the tx via gRPC.
grpcRes, err := qc.GetTxsEvent(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
require.GreaterOrEqual(t, len(grpcRes.Txs), 1)
require.Equal(t, "foobar", grpcRes.Txs[0].Body.Memo)
require.Equal(t, tc.expLen, len(grpcRes.Txs))

// Make sure fields are populated.
// ref: https://github.com/cosmos/cosmos-sdk/issues/8680
// ref: https://github.com/cosmos/cosmos-sdk/issues/8681
require.NotEmpty(t, grpcRes.TxResponses[0].Timestamp)
require.Empty(t, grpcRes.TxResponses[0].RawLog) // logs are empty if the transactions are successful
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in transaction event tests

The functions TestGetTxEvents_GRPC (lines 201-317) and TestGetTxEvents_GRPCGateway (lines 319-415) have significant overlap in their code. Refactoring shared code into helper functions can improve readability and reduce duplication.

Also applies to: 319-415

Comment on lines 742 to 855

qc := tx.NewServiceClient(sut.RPCClient(t))

// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
require.NoError(t, err)
invalidTxBytes := append(txBz, byte(0o00))

testCases := []struct {
name string
req *tx.TxDecodeRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"},
{"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"},
{"valid request with tx bytes", &tx.TxDecodeRequest{TxBytes: txBz}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res, err := qc.TxDecode(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
require.Empty(t, res)
} else {
require.NoError(t, err)
require.NotEmpty(t, res.GetTx())
}
})
}
}

func TestTxDecode_GRPCGateway(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
receiverAddr := cli.AddKey("account1")
denom := "stake"
var transferAmount int64 = 1000

sut.StartChain(t)

basrUrl := sut.APIAddress()

// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
require.NoError(t, err)
invalidTxBytes := append(txBz, byte(0o00))

testCases := []struct {
name string
req *tx.TxDecodeRequest
expErr bool
expErrMsg string
}{
{"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"},
{"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"},
{"valid request with tx_bytes", &tx.TxDecodeRequest{TxBytes: txBz}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
reqBz, err := json.Marshal(tc.req)
require.NoError(t, err)

res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode", basrUrl), "application/json", reqBz)
require.NoError(t, err)
if tc.expErr {
require.Contains(t, string(res), tc.expErrMsg)
} else {
signatures := gjson.Get(string(res), "tx.signatures").Array()
require.Equal(t, len(signatures), 1)
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in TestTxDecode_GRPC and TestTxDecode_GRPCGateway

The functions TestTxDecode_GRPC (lines 742-855) and TestTxDecode_GRPCGateway (lines 799-855) have similar code structures and duplicated logic. Refactoring shared code into helper functions can improve maintainability.

Also applies to: 799-855

Comment on lines +1093 to +1108
txJSONBytes, err := os.ReadFile("testdata/tx_amino1.json")
require.NoError(t, err)
var stdTx legacytx.StdTx
err = aminoCodec.UnmarshalJSON(txJSONBytes, &stdTx)
require.NoError(t, err)
return txJSONBytes, &stdTx
}

func readTestAminoTxBinary(t *testing.T, aminoCodec *codec.LegacyAmino) ([]byte, *legacytx.StdTx) {
txJSONBytes, err := os.ReadFile("testdata/tx_amino1.bin")
require.NoError(t, err)
var stdTx legacytx.StdTx
err = aminoCodec.Unmarshal(txJSONBytes, &stdTx)
require.NoError(t, err)
return txJSONBytes, &stdTx
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Combine similar helper functions for reading test transactions

The functions readTestAminoTxJSON (lines 1093-1100) and readTestAminoTxBinary (lines 1101-1108) are similar in functionality. Consider combining them into a single function that can handle both JSON and binary formats to reduce code duplication.

Also applies to: 1101-1108


sut.StartChain(t)

basrUrl := sut.APIAddress()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix typo in variable name 'basrUrl'

There's a typo in the variable name on line 814. It should be baseUrl instead of basrUrl to maintain consistency with other instances in the code.

Apply this diff to fix the typo:

-	basrUrl := sut.APIAddress()
+	baseUrl := sut.APIAddress()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
basrUrl := sut.APIAddress()
baseUrl := sut.APIAddress()

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c097fe5 and c1a0f75.

📒 Files selected for processing (1)
  • tests/systemtests/tx_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (3)
tests/systemtests/tx_test.go (3)

36-73: TestQueryBySig: Good test coverage

The TestQueryBySig function effectively tests querying transactions by signature. It sets up the necessary environment, constructs a transaction, and verifies that the correct transaction is retrieved based on the signature.


36-1071: Test suite provides comprehensive coverage

The added test functions cover various transaction scenarios, including querying, simulating, encoding, decoding, and multi-signature transactions. This comprehensive test suite aligns with the PR objectives and enhances the reliability of the transaction functionalities.


796-796: ⚠️ Potential issue

Fix typo in variable name

There's a typo on line 796: basrUrl should be baseUrl to maintain consistency and avoid confusion.

Apply this diff to correct the typo:

-	basrUrl := sut.APIAddress()
+	baseUrl := sut.APIAddress()

Likely invalid or redundant comment.

Comment on lines 75 to 135
func TestSimulateTx_GRPC(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
receiverAddr := cli.AddKey("account1")

sut.StartChain(t)

qc := tx.NewServiceClient(sut.RPCClient(t))

// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
require.NoError(t, err)

testCases := []struct {
name string
req *tx.SimulateRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.SimulateRequest{}, true, "empty txBytes is not allowed"},
{"valid request with tx_bytes", &tx.SimulateRequest{TxBytes: txBz}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Broadcast the tx via gRPC via the validator's clientCtx (which goes
// through Tendermint).
res, err := qc.Simulate(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
// Check the result and gas used are correct.
//
// The 12 events are:
// - Sending Fee to the pool: coin_spent, coin_received and transfer
// - tx.* events: tx.fee, tx.acc_seq, tx.signature
// - Sending Amount to recipient: coin_spent, coin_received and transfer
// - Msg events: message.module=bank, message.action=/cosmos.bank.v1beta1.MsgSend and message.sender=<val1> (in one message)
require.Equal(t, 10, len(res.GetResult().GetEvents()))
require.True(t, res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty.
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in simulation test functions

The functions TestSimulateTx_GRPC (lines 75-135) and TestSimulateTx_GRPCGateway (lines 137-197) contain significant duplicated code. Consider refactoring common setup and logic into helper functions to reduce redundancy and improve maintainability.

Also applies to: 137-197

Comment on lines 199 to 313
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)

rsp = cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake")
txResult, found = cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)

testCases := []struct {
name string
req *tx.GetTxsEventRequest
expErr bool
expErrMsg string
expLen int
}{
{
"nil request",
nil,
true,
"request cannot be nil",
0,
},
{
"empty request",
&tx.GetTxsEventRequest{},
true,
"query cannot be empty",
0,
},
{
"request with dummy event",
&tx.GetTxsEventRequest{Query: "foobar"},
true,
"failed to search for txs",
0,
},
{
"request with order-by",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
OrderBy: tx.OrderBy_ORDER_BY_ASC,
},
false,
"",
2,
},
{
"without pagination",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
},
false,
"",
2,
},
{
"with pagination",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
Page: 1,
Limit: 1,
},
false,
"",
1,
},
{
"with multi events",
&tx.GetTxsEventRequest{
Query: fmt.Sprintf("%s AND message.module='bank'", bankMsgSendEventAction),
},
false,
"",
2,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Query the tx via gRPC.
grpcRes, err := qc.GetTxsEvent(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
require.GreaterOrEqual(t, len(grpcRes.Txs), 1)
require.Equal(t, "foobar", grpcRes.Txs[0].Body.Memo)
require.Equal(t, tc.expLen, len(grpcRes.Txs))

// Make sure fields are populated.
// ref: https://github.com/cosmos/cosmos-sdk/issues/8680
// ref: https://github.com/cosmos/cosmos-sdk/issues/8681
require.NotEmpty(t, grpcRes.TxResponses[0].Timestamp)
require.Empty(t, grpcRes.TxResponses[0].RawLog) // logs are empty if the transactions are successful
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in transaction event test functions

The functions TestGetTxEvents_GRPC (lines 199-313) and TestGetTxEvents_GRPCGateway (lines 315-409) have substantial overlap. Refactoring shared code into reusable helper functions can enhance readability and reduce code duplication.

Also applies to: 315-409

Comment on lines 728 to 781
func TestTxDecode_GRPC(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
receiverAddr := cli.AddKey("account1")

sut.StartChain(t)

qc := tx.NewServiceClient(sut.RPCClient(t))

// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
require.NoError(t, err)
invalidTxBytes := append(txBz, byte(0o00))

testCases := []struct {
name string
req *tx.TxDecodeRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"},
{"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"},
{"valid request with tx bytes", &tx.TxDecodeRequest{TxBytes: txBz}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res, err := qc.TxDecode(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
require.Empty(t, res)
} else {
require.NoError(t, err)
require.NotEmpty(t, res.GetTx())
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in transaction decode test functions

The functions TestTxDecode_GRPC (lines 728-781) and TestTxDecode_GRPCGateway (lines 783-837) have similar structures and logic. Consolidate common code into helper functions to improve code maintainability.

Also applies to: 783-837

Comment on lines 1023 to 1070
func TestSimMultiSigTx(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
_ = cli.AddKey("account1")
_ = cli.AddKey("account2")

sut.StartChain(t)

multiSigName := "multisig"
cli.RunCommandWithArgs("keys", "add", multiSigName, "--multisig=account1,account2", "--multisig-threshold=2", "--keyring-backend=test", "--home=./testnet")
multiSigAddr := cli.GetKeyAddr(multiSigName)

// Send from validator to multisig addr
rsp := cli.Run("tx", "bank", "send", valAddr, multiSigAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)

multiSigBalance := cli.QueryBalance(multiSigAddr, denom)
require.Equal(t, multiSigBalance, transferAmount)

// Send from multisig to validator
// create unsign tx
var newTransferAmount int64 = 100
bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account1"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
account1Signed := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account2"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
account2Signed := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "multisign-batch", txFile.Name(), multiSigName, account1Signed.Name(), account2Signed.Name(), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
txSignedFile := StoreTempFile(t, []byte(res))

res = cli.Run("tx", "broadcast", txSignedFile.Name())
RequireTxSuccess(t, res)

multiSigBalance = cli.QueryBalance(multiSigAddr, denom)
require.Equal(t, multiSigBalance, transferAmount-newTransferAmount-10)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure proper error handling in multi-signature transaction test

In the TestSimMultiSigTx function (lines 1023-1070), consider adding error checks after running commands with cli.RunCommandWithArgs and cli.Run. While the test may fail if an error occurs, explicit error handling can provide clearer test failures and make debugging easier.

Comment on lines +411 to +456
func TestGetTx_GRPC(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
receiverAddr := cli.AddKey("account1")

sut.StartChain(t)

qc := tx.NewServiceClient(sut.RPCClient(t))

rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
txHash := gjson.Get(txResult, "txhash").String()

testCases := []struct {
name string
req *tx.GetTxRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.GetTxRequest{}, true, "tx hash cannot be empty"},
{"request with dummy hash", &tx.GetTxRequest{Hash: "deadbeef"}, true, "code = NotFound desc = tx not found: deadbeef"},
{"good request", &tx.GetTxRequest{Hash: txHash}, false, ""},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Query the tx via gRPC.
grpcRes, err := qc.GetTx(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
require.Equal(t, "foobar", grpcRes.Tx.Body.Memo)
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consolidate TestGetTx_GRPC and TestGetTx_GRPCGateway

The functions TestGetTx_GRPC (lines 411-456) and TestGetTx_GRPCGateway (lines 458-519) share similar code for testing transaction retrieval. Refactoring shared logic into helper functions can reduce duplication and improve test maintainability.

Also applies to: 458-519

Comment on lines +521 to +577
func TestGetBlockWithTxs_GRPC(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

// add new key
receiverAddr := cli.AddKey("account1")

sut.StartChain(t)

qc := tx.NewServiceClient(sut.RPCClient(t))

rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
height := gjson.Get(txResult, "height").Int()

testCases := []struct {
name string
req *tx.GetBlockWithTxsRequest
expErr bool
expErrMsg string
expTxsLen int
}{
{"nil request", nil, true, "request cannot be nil", 0},
{"empty request", &tx.GetBlockWithTxsRequest{}, true, "height must not be less than 1 or greater than the current height", 0},
{"bad height", &tx.GetBlockWithTxsRequest{Height: 99999999}, true, "height must not be less than 1 or greater than the current height", 0},
{"bad pagination", &tx.GetBlockWithTxsRequest{Height: height, Pagination: &query.PageRequest{Offset: 1000, Limit: 100}}, true, "out of range", 0},
{"good request", &tx.GetBlockWithTxsRequest{Height: height}, false, "", 1},
{"with pagination request", &tx.GetBlockWithTxsRequest{Height: height, Pagination: &query.PageRequest{Offset: 0, Limit: 1}}, false, "", 1},
{"page all request", &tx.GetBlockWithTxsRequest{Height: height, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 1},
{"block with 0 tx", &tx.GetBlockWithTxsRequest{Height: height - 1, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 0},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Query the tx via gRPC.
grpcRes, err := qc.GetBlockWithTxs(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
if tc.expTxsLen > 0 {
require.Equal(t, "foobar", grpcRes.Txs[0].Body.Memo)
}
require.Equal(t, grpcRes.Block.Header.Height, tc.req.Height)
if tc.req.Pagination != nil {
require.LessOrEqual(t, len(grpcRes.Txs), int(tc.req.Pagination.Limit))
}
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in block transaction retrieval tests

The functions TestGetBlockWithTxs_GRPC (lines 521-577) and TestGetBlockWithTxs_GRPCGateway (lines 579-637) have overlapping code. Consider extracting common code into reusable helper functions to enhance code clarity and reduce redundancy.

Also applies to: 579-637

Comment on lines +639 to +682
func TestTxEncode_GRPC(t *testing.T) {
sut.ResetChain(t)

cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)

sut.StartChain(t)

qc := tx.NewServiceClient(sut.RPCClient(t))

protoTx := &tx.Tx{
Body: &tx.TxBody{
Messages: []*codectypes.Any{},
},
AuthInfo: &tx.AuthInfo{},
Signatures: [][]byte{},
}

testCases := []struct {
name string
req *tx.TxEncodeRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"},
{"valid tx request", &tx.TxEncodeRequest{Tx: protoTx}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res, err := qc.TxEncode(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
require.Empty(t, res)
} else {
require.NoError(t, err)
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in transaction encode test functions

The functions TestTxEncode_GRPC (lines 639-682) and TestTxEncode_GRPCGateway (lines 684-726) perform similar operations for testing transaction encoding. Refactoring shared code into helper functions can improve code reuse and readability.

Also applies to: 684-726

Comment on lines +839 to +881
func TestTxEncodeAmino_GRPC(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)

legacyAmino := codec.NewLegacyAmino()
std.RegisterLegacyAminoCodec(legacyAmino)
legacytx.RegisterLegacyAminoCodec(legacyAmino)
legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend")

qc := tx.NewServiceClient(sut.RPCClient(t))
txJSONBytes, stdTx := readTestAminoTxJSON(t, legacyAmino)

testCases := []struct {
name string
req *tx.TxEncodeAminoRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxEncodeAminoRequest{}, true, "invalid empty tx json"},
{"invalid request", &tx.TxEncodeAminoRequest{AminoJson: "invalid tx json"}, true, "invalid request"},
{"valid request with amino-json", &tx.TxEncodeAminoRequest{AminoJson: string(txJSONBytes)}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res, err := qc.TxEncodeAmino(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
require.Empty(t, res)
} else {
require.NoError(t, err)
require.NotEmpty(t, res.GetAminoBinary())

var decodedTx legacytx.StdTx
err = legacyAmino.Unmarshal(res.AminoBinary, &decodedTx)
require.NoError(t, err)
require.Equal(t, decodedTx.GetMsgs(), stdTx.GetMsgs())
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in Amino transaction encode tests

The functions TestTxEncodeAmino_GRPC (lines 839-881) and TestTxEncodeAmino_GRPCGateway (lines 883-927) contain duplicated code. Consolidate common logic into helper functions to reduce code duplication and enhance maintainability.

Also applies to: 883-927

Comment on lines +929 to +973
func TestTxDecodeAmino_GRPC(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)

legacyAmino := codec.NewLegacyAmino()
std.RegisterLegacyAminoCodec(legacyAmino)
legacytx.RegisterLegacyAminoCodec(legacyAmino)
legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend")

qc := tx.NewServiceClient(sut.RPCClient(t))
encodedTx, stdTx := readTestAminoTxBinary(t, legacyAmino)

invalidTxBytes := append(encodedTx, byte(0o00))

testCases := []struct {
name string
req *tx.TxDecodeAminoRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxDecodeAminoRequest{}, true, "invalid empty tx bytes"},
{"invalid tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: invalidTxBytes}, true, "invalid request"},
{"valid request with tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: encodedTx}, false, ""},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res, err := qc.TxDecodeAmino(context.Background(), tc.req)
if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
require.Empty(t, res)
} else {
require.NoError(t, err)
require.NotEmpty(t, res.GetAminoJson())

var decodedTx legacytx.StdTx
err = legacyAmino.UnmarshalJSON([]byte(res.GetAminoJson()), &decodedTx)
require.NoError(t, err)
require.Equal(t, stdTx.GetMsgs(), decodedTx.GetMsgs())
}
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor duplicated code in Amino transaction decode tests

The functions TestTxDecodeAmino_GRPC (lines 929-973) and TestTxDecodeAmino_GRPCGateway (lines 975-1021) have similar structures. Refactoring shared code into reusable functions can improve code organization and reduce redundancy.

Also applies to: 975-1021

@julienrbrt julienrbrt added the backport/v0.52.x PR scheduled for inclusion in the v0.52's next stable release label Oct 22, 2024
@julienrbrt
Copy link
Member

Looks like the system tests (v1) are failing here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c1a0f75 and f6cbfd4.

📒 Files selected for processing (1)
  • tests/systemtests/tx_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

require.NoError(t, err)
msgResponses := gjson.Get(string(res), "result.msg_responses").Array()
require.Equal(t, len(msgResponses), 1)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Swap arguments in require.Equal assertions for correct order.

In the require.Equal assertions, the expected value should precede the actual value. The arguments are reversed in several places.

Examples:

  • Line 190: Change require.Equal(t, len(msgResponses), 1) to require.Equal(t, 1, len(msgResponses)).
  • Line 407: Change require.Equal(t, len(txs), tc.expLen) to require.Equal(t, tc.expLen, len(txs)).
  • Line 835: Change require.Equal(t, len(signatures), 1) to require.Equal(t, 1, len(signatures)).

Apply the following diffs:

190
-	require.Equal(t, len(msgResponses), 1)
+	require.Equal(t, 1, len(msgResponses))
407
-	require.Equal(t, len(txs), tc.expLen)
+	require.Equal(t, tc.expLen, len(txs))
835
-	require.Equal(t, len(signatures), 1)
+	require.Equal(t, 1, len(signatures))

Also applies to: 407-407, 835-835

signedTxFile := StoreTempFile(t, []byte(res))

res = cli.Run("tx", "broadcast", signedTxFile.Name())
fmt.Println("resss", res)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unnecessary fmt.Println statements.

The fmt.Println statements on lines 61 and 71 are unnecessary and should be removed to keep the test output clean.

Apply this diff:

61
-	fmt.Println("resss", res)
71
-	fmt.Println("resppp", resp)

Also applies to: 71-71

Comment on lines +127 to +132
// The 12 events are:
// - Sending Fee to the pool: coin_spent, coin_received and transfer
// - tx.* events: tx.fee, tx.acc_seq, tx.signature
// - Sending Amount to recipient: coin_spent, coin_received and transfer
// - Msg events: message.module=bank, message.action=/cosmos.bank.v1beta1.MsgSend and message.sender=<val1> (in one message)
require.Equal(t, 10, len(res.GetResult().GetEvents()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the expected number of events in the assertion or comment.

The comment mentions that there are 12 events expected, but the assertion checks for 10 events. This inconsistency should be addressed by updating the comment or the assertion to match the correct number of events.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f6cbfd4 and 9633dd0.

📒 Files selected for processing (1)
  • tests/systemtests/tx_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (1)
tests/systemtests/tx_test.go (1)

800-800: Fix typo in variable name basrUrl.

The variable basrUrl on line 800 is misspelled. It should be baseUrl to maintain consistency.

// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
unsignedTx := cli.RunCommandWithArgs(bankSendCmdArgs...)
fmt.Println("unsignedTx", unsignedTx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove unnecessary fmt.Println statement.

The fmt.Println statement on line 54 is unnecessary and can be removed to keep the test output clean.

txFile := StoreTempFile(t, []byte(unsignedTx))

signedTx := cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
fmt.Println("signedTx", signedTx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove unnecessary fmt.Println statement.

The fmt.Println statement on line 58 is unnecessary and can be removed to maintain clean test output.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 9633dd0 and ef39cdc.

📒 Files selected for processing (1)
  • tests/systemtests/tx_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (1)
tests/systemtests/tx_test.go (1)

58-58: 🛠️ Refactor suggestion

Remove unnecessary fmt.Println statement.

The fmt.Println statement on line 58 is unnecessary and can be removed to keep the test output clean.

Apply this diff to remove the unnecessary print statement:

-	fmt.Println("signedTx", signedTx)

Likely invalid or redundant comment.

require.Equal(t, len(msgResponses), 1)

events := gjson.Get(string(res), "result.events").Array()
require.Equal(t, len(events), 10)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order.

In the require.Equal assertion on line 194, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, len(events), 10)
+	require.Equal(t, 10, len(events))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
require.Equal(t, len(events), 10)
require.Equal(t, 10, len(events))

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
tests/systemtests/tx_test.go (3)

1086-1092: Rename variable 'txJSONBytes' to 'txBytes' for clarity

In the function readTestAminoTxBinary, the variable txJSONBytes is misleading because it reads binary data from tx_amino1.bin. Renaming it to txBytes improves code clarity.

Apply this diff to rename the variable:

 func readTestAminoTxBinary(t *testing.T, aminoCodec *codec.LegacyAmino) ([]byte, *legacytx.StdTx) {
-	txJSONBytes, err := os.ReadFile("testdata/tx_amino1.bin")
+	txBytes, err := os.ReadFile("testdata/tx_amino1.bin")
 	require.NoError(t, err)
 	var stdTx legacytx.StdTx
-	err = aminoCodec.Unmarshal(txJSONBytes, &stdTx)
+	err = aminoCodec.Unmarshal(txBytes, &stdTx)
 	require.NoError(t, err)
-	return txJSONBytes, &stdTx
+	return txBytes, &stdTx
 }

154-154: Remove unnecessary commented-out code

The commented-out code // qc := tx.NewServiceClient(sut.RPCClient(t)) appears unnecessary and can be removed to keep the codebase clean.

-	// qc := tx.NewServiceClient(sut.RPCClient(t))

758-758: Use hexadecimal notation for zero byte literal

Using byte(0x00) instead of byte(0o00) for the zero byte literal improves readability and is more commonly used.

Apply this diff for clarity:

-invalidTxBytes := append(txBz, byte(0o00))
+invalidTxBytes := append(txBz, byte(0x00))
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ef39cdc and f447dba.

📒 Files selected for processing (1)
  • tests/systemtests/tx_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (1)
tests/systemtests/tx_test.go (1)

800-800: ⚠️ Potential issue

Fix typo in variable name 'basrUrl'

There's a typo in the variable name on line 800. It should be baseUrl instead of basrUrl to maintain consistency with other instances in the code.

Apply this diff to correct the variable name:

-	basrUrl := sut.APIAddress()
+	baseUrl := sut.APIAddress()

Likely invalid or redundant comment.

tests/systemtests/tx_test.go Show resolved Hide resolved
@hieuvubk
Copy link
Contributor Author

Looks like the system tests (v1) are failing here.

it should work now

Copy link
Member

@julienrbrt julienrbrt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

Copy link
Contributor

@akhilkumarpilli akhilkumarpilli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK! nice work, small nit.

Comment on lines 306 to 307
// ref: https://github.com/cosmos/cosmos-sdk/issues/8680
// ref: https://github.com/cosmos/cosmos-sdk/issues/8681
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems these links are closed. Please remove if not necessary.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Outside diff range and nitpick comments (2)
tests/systemtests/tx_test.go (2)

985-985: Avoid appending null byte to transaction bytes

Appending a null byte (0o00) to invalidTxBytes may not effectively simulate an invalid transaction. Consider using invalid or corrupted transaction bytes for more robust testing.

You might generate invalid bytes like this:

invalidTxBytes := txBz[:len(txBz)-1]

854-855: Consistent error messages in test cases

In the test cases starting at line 854, the error messages in expErrMsg for invalid requests should be consistent and precise to facilitate accurate assertions.

Review and standardize the expErrMsg values for clarity and consistency.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f447dba and 75e408a.

📒 Files selected for processing (1)
  • tests/systemtests/tx_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
tests/systemtests/tx_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (5)
tests/systemtests/tx_test.go (5)

794-794: ⚠️ Potential issue

Fix typo in variable name basrUrl

There's a typo in the variable name on line 794. It should be baseUrl instead of basrUrl to maintain consistency with other instances in the code.

Apply this diff to fix the typo:

-	basrUrl := sut.APIAddress()
+	baseUrl := sut.APIAddress()

Likely invalid or redundant comment.


832-832: ⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order

In the require.Equal assertion on line 832, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, len(signatures), 1)
+	require.Equal(t, 1, len(signatures))

Likely invalid or redundant comment.


627-627: ⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order

In the require.Equal assertion on line 627, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, memo, "foobar")
+	require.Equal(t, "foobar", memo)

Likely invalid or redundant comment.


190-190: ⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order

In the require.Equal assertion on line 190, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, len(events), 10)
+	require.Equal(t, 10, len(events))

Likely invalid or redundant comment.


628-628: ⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order

In the require.Equal assertion on line 628, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, respHeight, height)
+	require.Equal(t, height, respHeight)

Likely invalid or redundant comment.

Comment on lines +1055 to +1058
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account1"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
account1Signed := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account2"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
account2Signed := StoreTempFile(t, []byte(res))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Check for errors after signing transactions

In the TestSimMultiSigTx function, the calls to cli.RunCommandWithArgs on lines 1055 and 1057 are not followed by error checks. Although the test may fail if an error occurs, explicit error handling can provide clearer test failures and make debugging easier.

Consider adding error checks after these commands:

res, err := cli.RunCommandWithArgs(/* arguments */)
require.NoError(t, err)

Comment on lines +745 to +748

res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Check for errors after signing and encoding transactions

In the TestTxDecode_GRPC function, after running cli.RunCommandWithArgs to sign and encode transactions, there are no error checks to confirm the commands executed successfully. Explicit error handling can improve test reliability.

Add error checks after signing and encoding:

res, err := cli.RunCommandWithArgs("tx", "sign", /* arguments */)
require.NoError(t, err)

res, err = cli.RunCommandWithArgs("tx", "encode", /* arguments */)
require.NoError(t, err)

account2Signed := StoreTempFile(t, []byte(res))

res = cli.RunCommandWithArgs("tx", "multisign-batch", txFile.Name(), multiSigName, account1Signed.Name(), account2Signed.Name(), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
txSignedFile := StoreTempFile(t, []byte(res))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Check for errors after multisigning transactions

In the TestSimMultiSigTx function, the call to cli.RunCommandWithArgs("tx", "multisign-batch", ...) on line 1061 does not include error handling. Adding an error check can help identify issues with the multisign process.

Add error handling:

res, err := cli.RunCommandWithArgs("tx", "multisign-batch", /* arguments */)
require.NoError(t, err)

Comment on lines +616 to +617
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/%d", baseUrl, height),
false, "",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure proper error handling for HTTP requests

In the TestGetBlockWithTxs_GRPCGateway function, after calling testutil.GetRequest, the code checks require.NoError(t, err) but does not handle HTTP error responses that might not set err. Consider checking the HTTP status code or response content for error indications.

Add checks to handle HTTP errors appropriately.

} else {
require.NoError(t, err)
msgResponses := gjson.Get(string(res), "result.msg_responses").Array()
require.Equal(t, len(msgResponses), 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order

In the require.Equal assertion on line 187, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, len(msgResponses), 1)
+	require.Equal(t, 1, len(msgResponses))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
require.Equal(t, len(msgResponses), 1)
require.Equal(t, 1, len(msgResponses))

} else {
require.NoError(t, err)
txs := gjson.Get(string(res), "txs").Array()
require.Equal(t, len(txs), tc.expLen)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Swap arguments in require.Equal assertion for correct order

In the require.Equal assertion on line 403, the expected value should precede the actual value. The arguments are currently reversed.

Apply this diff to correct the assertion:

-	require.Equal(t, len(txs), tc.expLen)
+	require.Equal(t, tc.expLen, len(txs))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
require.Equal(t, len(txs), tc.expLen)
require.Equal(t, tc.expLen, len(txs))

reqBz, err := json.Marshal(tc.req)
require.NoError(t, err)

res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode/amino", baseUrl), "application/json", reqBz)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential errors when decoding responses

In the TestTxDecodeAmino_GRPCGateway function, the error returned by json.Unmarshal on line 1009 is being shadowed. Ensure that the error variable is not redeclared to avoid unintended behavior.

Apply this diff to fix the error handling:

-	err := json.Unmarshal(res, &result)
+	err = json.Unmarshal(res, &result)

Committable suggestion was skipped due to low confidence.

@hieuvubk hieuvubk enabled auto-merge October 24, 2024 08:26
@hieuvubk hieuvubk added this pull request to the merge queue Oct 24, 2024
Merged via the queue into main with commit ea219a2 Oct 24, 2024
72 of 73 checks passed
@hieuvubk hieuvubk deleted the hieu/systemtest/tx branch October 24, 2024 09:24
mergify bot pushed a commit that referenced this pull request Oct 24, 2024
alpe added a commit that referenced this pull request Oct 25, 2024
* main: (157 commits)
  feat(core): add ConfigMap type (#22361)
  test: migrate e2e/genutil to systemtest (#22325)
  feat(accounts): re-introduce bundler (#21562)
  feat(log): add slog-backed Logger type (#22347)
  fix(x/tx): add feePayer as signer (#22311)
  test: migrate e2e/baseapp to integration tests (#22357)
  test: add x/circuit system tests (#22331)
  test: migrate e2e/tx tests to systemtest (#22152)
  refactor(simdv2): allow non-comet server components (#22351)
  build(deps): Bump rtCamp/action-slack-notify from 2.3.1 to 2.3.2 (#22352)
  fix(server/v2): respect context cancellation in start command (#22346)
  chore(simdv2): allow overriding the --home flag (#22348)
  feat(server/v2): add SimulateWithState to AppManager (#22335)
  docs(x/accounts): improve comments (#22339)
  chore: remove unused local variables (#22340)
  test: x/accounts systemtests (#22320)
  chore(client): use command's configured output (#22334)
  perf(log): use sonic json lib  (#22233)
  build(deps): bump x/tx (#22327)
  fix(x/accounts/lockup): fix proto path (#22319)
  ...
julienrbrt pushed a commit that referenced this pull request Oct 27, 2024
Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com>
@coderabbitai coderabbitai bot mentioned this pull request Oct 29, 2024
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/v0.52.x PR scheduled for inclusion in the v0.52's next stable release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

tests/e2e/tx to system tests
3 participants