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: v2 services helpers and demo using x/bank #23057

Open
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

aljo242
Copy link
Contributor

@aljo242 aljo242 commented Dec 20, 2024

Description

Part of: #22903

  • expand the core testing package to return more services and a TestContext and TestEnvironment wrapper that can be used throughout module and keeper-level tests
  • demo in x/bank test, removing all uses of baseapp and sdk.Context

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

Release Notes

  • New Features

    • Enhanced testing framework with new TestContext and TestEnvironment management.
    • Introduced mock services for gas, header, and transaction handling in testing scenarios.
    • Added reflection-based router for flexible handler management.
    • New QueryHelper struct for building query clients in a testing context.
  • Improvements

    • Streamlined context handling across multiple testing components.
    • Simplified handler registration for message and query routers.
    • Updated module and keeper tests to utilize the new testing infrastructure.
    • Improved clarity and maintainability of test code by removing unnecessary complexity.

These changes primarily focus on enhancing the testing capabilities and infrastructure for the Cosmos SDK, providing more robust and flexible testing mechanisms.

}

// WithGas sets the gas config and meter on a testing ctx and returns the updated ctx.
func (t TestContext) WithGas(gasConfig gas.GasConfig, gasMeter gas.Meter) TestContext {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created the TestContext wrapper so that we can extend with methods to modify it like the ones here


type TestEnvironment struct {
env appmodulev2.Environment
memEventsService MemEventsService
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Include the concrete types of our Mem services so that we can use the additional helper methods (such as GetEvents) in our tests

Copy link
Contributor

coderabbitai bot commented Dec 20, 2024

📝 Walkthrough

Walkthrough

This pull request introduces a new testing framework for the Cosmos SDK, focusing on enhancing context management and service mocking. It establishes a coretesting package that provides robust testing utilities across various modules. Key features include the creation of a TestContext type, memory services for components like headers, gas, and transactions, and a reflection-based router for handling message routing during tests. Additionally, several test files have been updated to utilize the new testing framework and context management strategies.

Changes

File Change Summary
core/testing/context.go Introduced TestContext implementing context.Context with additional methods for header, execution mode, and gas configuration.
core/testing/environment.go Added TestEnvironmentConfig and TestEnvironment for structured test setup.
core/testing/gas.go, header.go, transaction.go Created memory services for gas, headers, and transactions with mock implementations.
core/testing/router.go Implemented a reflection-based router for message handling in tests.
core/testing/event.go Replaced MemEventsService with TestEventService and updated associated methods.
x/bank/go.mod Modified dependency management for the bank module.
x/bank/keeper/*_test.go Updated test suites to use new testing framework and context.
x/bank/types/*_test.go Adjusted context handling in tests to use standard Go context.
x/bank/v2/keeper/handlers.go Added methods for registering message and query handlers.
x/bank/v2/module.go Refactored message and query handler registration to utilize new handler methods.
tests/integration/distribution/genesis_test.go Reorganized import statements for clarity.
testutil/queryclient/queryclient.go Introduced QueryHelper for building a query client from a proto interface registry.

Possibly related PRs

Suggested labels

C:server/v2

Suggested reviewers

  • tac0turtle
  • julienrbrt
  • sontrinh16
  • kocubinski
  • testinginprod

📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f56126 and f67b33f.

📒 Files selected for processing (1)
  • x/bank/keeper/grpc_query_test.go (18 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • x/bank/keeper/grpc_query_test.go
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Analyze
  • GitHub Check: tests (03)
  • GitHub Check: tests (00)
  • GitHub Check: test-simapp-v2
  • GitHub Check: test-integration
  • GitHub Check: test-system-v2
  • GitHub Check: build (amd64)
  • GitHub Check: Summary

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

var ErrNoHandler = errors.New("no handler")

// NewMsgRouterBuilder is a router that routes messages to their respective handlers.
func NewMsgRouterBuilder() *ReflectionRouterBuilder {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Core-only router builder that uses reflect instead of protoreflect for test pathfinding

core/testing/router.go Dismissed Show dismissed Hide dismissed
core/testing/router.go Dismissed Show dismissed Hide dismissed
@aljo242 aljo242 marked this pull request as ready for review January 3, 2025 17:30
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

🧹 Nitpick comments (31)
core/testing/context.go (1)

22-36: Constructor Naming Consistency

The Context() function creates a TestContext instance with a backing dummy context. In Go, constructors for exported types conventionally follow the NewXxx naming (e.g., NewTestContext). Changing the function name may improve discoverability and consistency.

core/testing/router.go (1)

151-159: Invoke Method and Reflection

Invoke uses reflect.TypeOf(req).String() as the message key. This is functional, though storing a type’s string name might risk collisions if two types share the same string. Typically, a type URL or fully qualified name is used. For test scenarios, it’s likely acceptable.

core/testing/services_test.go (1)

9-15: Prefer a no-op logger over nil for clarity and maintainability.

Although supplying a nil logger may be acceptable in certain test scenarios, it can make debugging more difficult when tests fail unexpectedly. Consider using a no-op or in-memory logger so any logging statements can still be captured if needed for troubleshooting.

core/testing/environment.go (2)

13-18: Consider providing default routers or explanatory comments for nil values.

The new TestEnvironmentConfig allows users to configure a logger and routers but defaults them to nil. This is fine when certain services aren’t strictly required. However, adding default, no-op implementations or clarifying comments could help other contributors understand when and why a nil router is acceptable.


20-24: Implement or document the missing MemStoreService.

Currently, MemStoreService is set to nil in the returned appmodulev2.Environment. This may be intentional if your module doesn’t require it. Otherwise, providing a minimal, concrete MemStoreService would allow consistent usage with other memory-based services.

Do you want help implementing a basic MemStoreService for uniform coverage in your test environment?

x/bank/v2/keeper/handlers.go (1)

Line range hint 42-66: Consolidate repeated authority checks into a helper.

Your authority validation logic appears in both MsgUpdateParams and MsgMint. Extracting this into a small helper method can improve maintainability and clarity by centralizing the checks (e.g., matching addresses, string conversion, and error handling).

x/bank/types/send_authorization_test.go (1)

32-32: No logic to handle non-zero gas consumption
The current implementation always returns nil. Consider tracking or logging gas usage to ensure correct metering in tests.

x/bank/keeper/grpc_query_test.go (8)

104-104: Empty request scenario
Raising errors for empty requests is correct. Consider adding negative tests to confirm robust handling of malformed queries.


145-145: Second page logic
When retrieving the second page of results, verify that you handle edge cases where fewer results may exist.


183-185: Combining test setup
Lines 183 and 185 define ctx and queryClient. Re-evaluate for consistent usage across all sub-tests (e.g., some tests may set up their own context).


213-214: Use Unix timestamps
Casting block time to Unix() is valid for vesting calculations. Confirm that all time-based logic consistently uses the same epoch reference.


237-240: Initialize second test context
Setting ctx and queryClient again here might override previous test contexts. Ensure no state from prior tests is inadvertently shared.


Line range hint 296-305: Testing total supply updates
Ensure correct supply increments after module minting. Verify no conflict with previously minted coins.


333-333: Zero supply fallback
Returning zero supply for an unknown denom is standard. This is consistent with typical chain logic.


350-350: Empty metadata slice
Initializing expMetadata as an empty slice ensures no nil pointer usage. This improves test robustness.

x/bank/types/restrictions_test.go (1)

392-392: No-op minting restriction
Confirm that this function is intentionally lenient and won't impede future expansions to minted coins logic.

x/bank/keeper/keeper_test.go (15)

21-21: Added logging import
Using log might be optional if no actual logs are emitted here. Keep the import if relevant logs may be added later.


132-137: Initialize custom TestEnvironmentConfig
These lines define the environment config (logger, routers, etc.). Verify you have included all necessary modules in the router for advanced tests.


139-140: Create environment
coretesting.NewTestEnvironment is used. Check for concurrency issues if tests run in parallel, especially around shared static resources.


174-174: Store encCfg
Retaining encCfg in the suite helps additional test methods decode messages.


220-220: mockSpendableCoins
Ensuring vesting accounts are retrieved from the new environment context is proper. Verify no usage of the older sdk.Context.


1406-1406: Reset context
Ensure you reset any test state needed prior to the new multi-send tests.


1459-1459: 25 events
The test scenario triggers multiple events. Make sure all event sources (like mint/spend/recv) are well-documented.


1493-1494: Validate key match
Ensuring the attribute keys align with the expected static references from bank types.


1510-1510: TestSpendableBalances
Setting up multiple vesting scenarios here is important. Confirm partial and fully vested cases are tested thoroughly.


1664-1664: Additional periodic vesting test
Validates that new coins remain separated from the original vesting schedule, ensuring no accidental lumps in vesting logic.


1760-1760: UndelegateCoins
The test ensures that previously delegated coins are returned to the correct account. Double-check partial undelegations as well.


1770-1770: ContinuousVestingAccount usage
At line 1770, you retrieve the header info to initialize vesting. Confirm alignment with partial or periodic vesting tests.


1940-1940: Handled coin mint
Add minted coins to your in-test supply tracking. This ensures minted amounts match keeper logic.


1947-1947: Check address decode
At line 1947, verifying that the address can be parsed by the codec is crucial to avoid panics.


1957-1957: Tracking final balances
Ensuring all local balances sum up correctly after each event is crucial for supply integrity checks.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07d5168 and c7bc69d.

⛔ Files ignored due to path filters (1)
  • x/bank/go.sum is excluded by !**/*.sum
📒 Files selected for processing (14)
  • core/testing/context.go (2 hunks)
  • core/testing/environment.go (1 hunks)
  • core/testing/gas.go (1 hunks)
  • core/testing/header.go (1 hunks)
  • core/testing/router.go (1 hunks)
  • core/testing/services_test.go (1 hunks)
  • core/testing/transaction.go (1 hunks)
  • x/bank/go.mod (2 hunks)
  • x/bank/keeper/grpc_query_test.go (17 hunks)
  • x/bank/keeper/keeper_test.go (21 hunks)
  • x/bank/types/restrictions_test.go (4 hunks)
  • x/bank/types/send_authorization_test.go (2 hunks)
  • x/bank/v2/keeper/handlers.go (2 hunks)
  • x/bank/v2/module.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • x/bank/go.mod
🧰 Additional context used
📓 Path-based instructions (13)
core/testing/transaction.go (1)

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

x/bank/keeper/grpc_query_test.go (2)

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


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

core/testing/gas.go (1)

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

core/testing/header.go (1)

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

x/bank/types/send_authorization_test.go (2)

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


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

x/bank/v2/keeper/handlers.go (1)

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

x/bank/types/restrictions_test.go (2)

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


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

core/testing/services_test.go (2)

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


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

core/testing/context.go (1)

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

core/testing/environment.go (1)

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

x/bank/v2/module.go (1)

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

x/bank/keeper/keeper_test.go (2)

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


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

core/testing/router.go (1)

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

🔇 Additional comments (65)
core/testing/context.go (6)

16-17: Interfaces Confirmed Implemented

Declaring var _ context.Context = &TestContext{} is a good practice to ensure TestContext satisfies the context.Context interface. No issues here.


38-52: Interface Pass-Through Methods

Deadline(), Done(), Err(), and Value() correctly pass through to the underlying context. This approach cleanly preserves the original context behaviors. No concerns.


54-63: Builder Pattern for Header

WithHeaderInfo follows a fluent, builder-like pattern, returning a new TestContext with updated header info. This pattern is clear and test-friendly. Ensure that any code depending on the old context references is aware that changes won't reflect retroactively.


64-72: Builder Pattern for ExecMode

WithExecMode also returns a new TestContext, mirroring WithHeaderInfo logic. This consistency is beneficial. No issues found.


74-82: Builder Pattern for Gas

WithGas retains the same pattern, setting gas config and meter in a new dummyCtx. This approach is consistent with the rest of the file and supports test flexibility.


92-97: Potential Concurrency Considerations for Maps

dummyCtx stores data in maps which are not thread-safe. If test scenarios evolve to run in parallel, consider adding synchronization or clarifying usage in single-threaded tests to avoid data races.

core/testing/router.go (9)

14-15: Exported Error Variable

ErrNoHandler is properly declared and used in error returns. This ensures consistent error signaling. No issues found.


16-23: Reflection-Based Router Initialization

NewMsgRouterBuilder() instantiates the ReflectionRouterBuilder along with handler maps. The approach is straightforward. If performance becomes critical, consider alternatives to reflection, but for a test or dev environment, it is adequate.


25-31: ReflectionRouterBuilder Data Structures

Storing handlers in maps keyed by string is direct and easy to maintain. Avoid overriding already-registered handlers is a good safeguard. No immediate concerns.


33-40: RegisterHandler Override Check

The function panics on handler override, which can be beneficial to detect accidental re-registrations in tests. This explicit error handling is acceptable for testing scenarios.


42-56: Global vs. Local Handlers

The builder allows both global pre/post handlers and msg-specific handlers. This design is flexible and well-structured for test-centric message routing. No issues found.


58-61: HandlerExists Helper

HandlerExists is a neat utility to verify registration status. Straightforward approach, no concerns.


63-98: Build Method: Consolidated Handler Assembly

Aggregating the global and per-message pre/post handlers into final HandlerFuncs is clean. Using closures for each built handler is a neat approach. Reflection overhead is likely acceptable in test contexts.


100-134: buildHandler Implementation

Sequentially running pre-handlers, calling the main handler, then post-handlers is logically grouped and easy to follow. The returning of (nil, err) ensures short-circuiting on failures. Looks good.


143-149: CanInvoke Method

Reports an error if there's no matching handler. This method is simple yet effective for verifying route coverage in tests.

core/testing/header.go (2)

9-10: Interface Conformance

MemHeaderService correctly implements header.Service. The _ = &MemHeaderService{} check ensures compile-time conformance.


13-15: Header Retrieval via unwrap

HeaderInfo returns dummy.header. For test usage, it’s straightforward. The usage of panic in unwrap is acceptable in a purely testing context.

core/testing/transaction.go (2)

9-10: Transaction Service Conformance

MemTransactionService satisfies the transaction.Service interface. No issues with _ = &MemTransactionService{} usage.


13-17: ExecMode from Context

Extracting execMode from the dummyCtx is consistent with other wrappers. Ensure that if parallel tests access the same context, there's no conflicting usage. Typically, each test should have its own context instance.

core/testing/gas.go (3)

9-10: Gas Service Conformance

MemGasService fulfills gas.Service. The _ = &MemGasService{} check is standard for interface compliance.


13-17: GasMeter Getter

GasMeter fetches the meter from dummyCtx. Straightforward approach. No issues found.


19-23: GasConfig Getter

GasConfig also delegates to dummyCtx. This is consistent with other services. Looks good.

x/bank/v2/module.go (2)

97-97: Modular registration of message handlers looks great.

Delegating the registration process to keeper.NewHandlers(am.keeper).RegisterMsgHandlers(router) improves maintainability and promotes encapsulation.


103-103: Query handlers are similarly well-encapsulated.

Registering the queries through the keeper’s RegisterQueryHandlers method is consistent with the message handlers approach. This keeps logic for query routing cohesive and testable.

x/bank/v2/keeper/handlers.go (1)

29-34: Straightforward approach for registering message handlers.

Using appmodulev2.RegisterMsgHandler to wire up your message endpoints is clear. Ensure you keep adding new messages here to avoid missing coverage.

x/bank/types/send_authorization_test.go (2)

10-10: Streamlined import usage
Importing coretesting aligns with the new testing framework and is consistent with best practices.


38-44: New test environment configuration
Initializing a TestEnvironmentConfig and injecting a mock gas meter is a suitable approach for modular tests. Verify that all required test services (e.g., event managers) are also configured as needed.

x/bank/keeper/grpc_query_test.go (12)

86-86: Validate error checking
Ensure that all expected errors are thoroughly tested when querying balances.


116-116: Beware of pagination
Properly verify pagination in tests to ensure correct iteration over balances.


132-132: Check result struct shape
Ensure the returned response structure matches the expected fields in gRPC stubs for multi-balance queries.


159-159: Ensure non-empty 3rd page
Properly handle the scenario where the 3rd page might still contain valid results.


171-171: Resolve denom
The final test checks IBC denom resolution. Ensure correct mapping between the resolution logic and the IBC coin metadata.


207-208: Accessing currentBlockTime
Fetching the header time from suite.env.HeaderService().HeaderInfo(ctx).Time is consistent with the new environment approach. Ensure synchronization with how vesting logic uses time.


222-223: Updated context with new header
Modifying the context with a new time helps simulate the vesting mid-way. Confirm that subsequent calls indeed observe this updated time.


260-261: BlockTime retrieval
Repeating the block time fetch. Make sure to keep usage consistent for multi-step vesting tests.


266-267: Accurate vesting start & end
Double-check that the vesting intervals match expectations in the test scenario.


275-276: Advance half vesting
After 30 minutes, verify partial vesting. The test coverage is good for progressive vesting checks.


324-327: Query supply
At line 324 and 327, test partial supply queries by denom. Confirm error handling for nonexistent denoms.


340-341: Params query
Lines 340,341 and 344 validate the bank params query. Confirm default param usage and non-empty param sets.

Also applies to: 344-344

x/bank/types/restrictions_test.go (3)

86-86: Resizing the calls slice
Resetting s.Calls before invocation is crucial. Ensure no leftover state pollutes subsequent assertions.


486-486: Capturing function output
Storing returned addr and err ensures test clarity. Good approach to isolate each call’s state.


915-915: Testing NoOpSendRestriction
This test is straightforward. Confirm unexpected error scenarios are also tested if future modifications are introduced.

x/bank/keeper/keeper_test.go (23)

114-115: Switch to coretesting.TestContext
These changes replace standard contexts with coretesting.TestContext, aligning with the new test environment approach. This is consistent with the PR objective.


120-120: QueryServer reference
Switching from a QueryClient to a QueryServer is consistent with the updated gRPC design. Confirm all client calls are updated accordingly.


156-156: Set up BaseKeeper
Providing environment-based references is a better pattern than global singletons. Keep an eye on unauthorized usage of environment resources.


169-169: Initialize QueryServer
keeper.NewQuerier returns a QueryServer. Confirm that registry is up-to-date for all query endpoints.


171-171: Attach MsgServer
Attaching a MsgServer to the newly created keeper is crucial for covering message functionalities in tests.


1389-1396: New event service usage
Shifting to suite.env.MemEventsService() to retrieve events is a modern approach. Carefully review event indexing for large or repeated tests.


1399-1401: Comparing custom attributes
Ensuring that each event attribute matches the test expectation is correct. This thoroughly validates event emission.


1434-1434: Events array length
You verify that no events appear yet. This ensures the test data is fully controlled.


1444-1444: Check events after second transaction
Ensure no overlap from previous events. Good to confirm final length as 10 in this scenario.


1488-1491: Comparing Transfer events
The test ensures that the event type is “transfer,” referencing the correct attributes (sender/recipient/amount). Good coverage.


1499-1502: Second Transfer event
Similarly verifying the second transfer event’s attributes. Consistent approach to multi-send testing.


1504-1505: Check final attributes
Ensuring the final comparisons match the expected attribute list for each transfer.


1566-1566: Test vesting logic
The continuous vesting logic is tested halfway through the vesting period. Great approach to ensure partial unlocking is correct.


1596-1596: Periodic vesting
Combining multiple vesting periods tests more complex logic. Check that newly minted or transferred coins do not unexpectedly vest.


1631-1631: Test receiving coins
Verifies that newly received coins are immediately spendable even in vesting accounts—important difference from original vesting coins.


1702-1702: DelegateCoins
Test includes delegating from both vesting and normal accounts. This coverage is crucial to ensure partial locked funds.


1712-1712: Use of suite.env.HeaderService()
Line 1712 references the environment’s header data. It’s consistent with the new testing infrastructure.


1928-1928: Event-based supply tracking
Reading all events from suite.env.MemEventsService().GetEvents(suite.ctx) helps confirm supply is correctly minted and burned.


1930-1932: Wrapping event attributes
Parsing event attributes carefully avoids indexing errors. Consider additional validations for event order or duplicates.


1935-1935: Handled coin burn
Subtract burned coins from total supply. Good approach to reflect deflationary events in your test logic.


1945-1945: Handled coin spent
Ensuring the spent coins are subtracted from the correct local address balance. Good for validating no misattribution.


1950-1950: Decrement balance
Properly subtracting spent coins from the relevant address’s local tracking.


1953-1955: Handled coin received
Adding coins to the address’s local tracking. Continues the event-driven verification approach.

Comment on lines 26 to 52
func NewTestEnvironment(cfg TestEnvironmentConfig) (TestContext, TestEnvironment) {
ctx := Context()

memEventService := EventsService(ctx, cfg.ModuleName)
memHeaderService := MemHeaderService{}

env := TestEnvironment{
env: appmodulev2.Environment{
Logger: cfg.Logger,
BranchService: nil,
EventService: memEventService,
GasService: MemGasService{},
HeaderService: memHeaderService,
QueryRouterService: cfg.QueryRouter,
MsgRouterService: cfg.MsgRouter,
TransactionService: MemTransactionService{},
KVStoreService: KVStoreService(ctx, cfg.ModuleName),
MemStoreService: nil,
},
memEventsService: memEventService,
memHeaderService: memHeaderService,
}

// set internal context to point to environment
ctx.ctx = context.WithValue(ctx.ctx, corecontext.EnvironmentContextKey, env.env)
return ctx, env
}

This comment was marked as off-topic.

Comment on lines +36 to +40
// RegisterQueryHandlers registers the query handlers to the router.
func (h handlers) RegisterQueryHandlers(router appmodulev2.QueryRouter) {
appmodulev2.RegisterMsgHandler(router, h.QueryParams)
appmodulev2.RegisterMsgHandler(router, h.QueryBalance)
}
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

Potentially incorrect usage of message-handling registration for queries.

Both QueryParams and QueryBalance are query endpoints, yet they're being registered with RegisterMsgHandler. This can cause confusion and possibly route queries incorrectly. To align with naming conventions, use a dedicated query registration method, such as appmodulev2.RegisterQueryHandler(router, ...), to register query endpoints.

-func (h handlers) RegisterQueryHandlers(router appmodulev2.QueryRouter) {
-	appmodulev2.RegisterMsgHandler(router, h.QueryParams)
-	appmodulev2.RegisterMsgHandler(router, h.QueryBalance)
+func (h handlers) RegisterQueryHandlers(router appmodulev2.QueryRouter) {
+	appmodulev2.RegisterQueryHandler(router, h.QueryParams)
+	appmodulev2.RegisterQueryHandler(router, h.QueryBalance)
 }
📝 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
// RegisterQueryHandlers registers the query handlers to the router.
func (h handlers) RegisterQueryHandlers(router appmodulev2.QueryRouter) {
appmodulev2.RegisterMsgHandler(router, h.QueryParams)
appmodulev2.RegisterMsgHandler(router, h.QueryBalance)
}
// RegisterQueryHandlers registers the query handlers to the router.
func (h handlers) RegisterQueryHandlers(router appmodulev2.QueryRouter) {
appmodulev2.RegisterQueryHandler(router, h.QueryParams)
appmodulev2.RegisterQueryHandler(router, h.QueryBalance)
}

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.

Concept ACK. Services mock makes sense to me!

Copy link
Contributor

@technicallyty technicallyty left a comment

Choose a reason for hiding this comment

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

small nits and stuff

core/testing/gas.go Outdated Show resolved Hide resolved
core/testing/header.go Outdated Show resolved Hide resolved
core/testing/router.go Outdated Show resolved Hide resolved
var ErrNoHandler = errors.New("no handler")

// NewMsgRouterBuilder is a router that routes messages to their respective handlers.
func NewMsgRouterBuilder() *ReflectionRouterBuilder {
Copy link
Contributor

Choose a reason for hiding this comment

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

my IDE says there are no usages of this function - is there an example usage of this somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This would be used for an appmodulev2 module - which this task doesn't touch

Copy link
Contributor

Choose a reason for hiding this comment

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

adding comment here from our conversation so we don't forget: resolution here is to add a test that utilizes this code in some way

core/testing/transaction.go Outdated Show resolved Hide resolved
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: 0

🔭 Outside diff range comments (2)
core/testing/context.go (1)

Line range hint 1-10: Fix import ordering to comply with linting rules.

The imports need to be reordered using gci with the following configuration:

  • standard
  • default
  • prefix(cosmossdk.io)
  • prefix(github.com/cosmos/cosmos-sdk)
#!/bin/bash
# Fix import ordering
gci write --skip-generated -s standard -s default -s "prefix(cosmossdk.io)" -s "prefix(github.com/cosmos/cosmos-sdk)" core/testing/context.go
🧰 Tools
🪛 golangci-lint (1.62.2)

4-4: File is not gci-ed with --skip-generated -s standard -s default -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) --custom-order

(gci)

🪛 GitHub Actions: Lint

[error] 4-4: File is not gci-ed with --skip-generated -s standard -s default -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) --custom-order

x/bank/keeper/keeper_test.go (1)

Line range hint 1760-1770: Replace time.Now() with deterministic timestamps in tests.

Using time.Now() can lead to flaky tests. Consider using fixed timestamps for better test reliability.

-now := time.Now()
-endTime := now.Add(24 * time.Hour)
+baseTime := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
+endTime := baseTime.Add(24 * time.Hour)

-vacc, err := vesting.NewContinuousVestingAccount(acc0, origCoins, suite.env.HeaderService().HeaderInfo(ctx).Time.Unix(), endTime.Unix())
+vacc, err := vesting.NewContinuousVestingAccount(acc0, origCoins, baseTime.Unix(), endTime.Unix())
🧹 Nitpick comments (4)
core/testing/context.go (3)

20-34: Add documentation for the Context() function.

The function should be documented to explain:

  • Its purpose in creating a new test context
  • The initialization of default values
  • The return value
+// Context creates a new TestContext initialized with default values.
+// It returns a TestContext that wraps a context.Context with testing-specific values.
 func Context() TestContext {

36-64: Consider refactoring common patterns and adding documentation.

The context modification methods share a common pattern that could be abstracted to reduce code duplication. Additionally, each method should be documented.

Consider creating a helper function for the common pattern:

+// withValue is a helper function that unwraps the dummy context, applies the modifier function,
+// and returns a new TestContext with the modified value.
+func (t TestContext) withValue(modifier func(*dummyCtx)) TestContext {
+    dummy := unwrap(t.Context)
+    modifier(dummy)
+    return TestContext{
+        Context: context.WithValue(t.Context, dummyKey{}, dummy),
+    }
+}

+// WithHeaderInfo sets the header information on the test context.
 func (t TestContext) WithHeaderInfo(info header.Info) TestContext {
-    dummy := unwrap(t.Context)
-    dummy.header = info
-    return TestContext{
-        Context: context.WithValue(t.Context, dummyKey{}, dummy),
-    }
+    return t.withValue(func(dummy *dummyCtx) {
+        dummy.header = info
+    })
 }

Line range hint 66-91: Improve error handling and documentation in dummyCtx.

Consider the following improvements:

  1. Replace panic with error return in unwrap function
  2. Add documentation for dummyCtx fields
 type dummyCtx struct {
+    // stores maps store by actor
     stores map[string]store.KVStore
+    // events maps event emitted by actor
     events map[string][]event.Event
+    // protoEvents maps proto events emitted by actor
     protoEvents map[string][]transaction.Msg

+    // header contains the current header information
     header   header.Info
+    // execMode defines the current execution mode
     execMode transaction.ExecMode

+    // gasMeter tracks gas consumption
     gasMeter  gas.Meter
+    // gasConfig defines gas parameters
     gasConfig gas.GasConfig
 }

-func unwrap(ctx context.Context) *dummyCtx {
+func unwrap(ctx context.Context) (*dummyCtx, error) {
     dummy := ctx.Value(dummyKey{})
     if dummy == nil {
-        panic("invalid ctx without dummy")
+        return nil, fmt.Errorf("invalid ctx without dummy")
     }
-    return dummy.(*dummyCtx)
+    return dummy.(*dummyCtx), nil
 }
x/bank/keeper/keeper_test.go (1)

1389-1402: Consider refactoring event assertions for better maintainability.

The event assertions could be improved by:

  1. Creating a helper function to compare events
  2. Adding comments explaining the event offset (why events are shifted by 7)
+// assertEvent compares an expected event with an actual event
+func (suite *KeeperTestSuite) assertEvent(expected, actual coreevent.Event) {
+    suite.Require().Equal(expected.Type, actual.Type)
+    expectedAttrs, err := expected.Attributes()
+    suite.Require().NoError(err)
+    actualAttrs, err := actual.Attributes()
+    suite.Require().NoError(err)
+    suite.Require().Equal(expectedAttrs, actualAttrs)
+}

 events := suite.env.MemEventsService().GetEvents(suite.ctx)
+// events[7] is the transfer event (previous events are from account funding)
 require.Equal(event1.Type, events[7].Type)
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d29ed65 and d42ac1f.

📒 Files selected for processing (4)
  • core/testing/context.go (2 hunks)
  • core/testing/environment.go (1 hunks)
  • tests/integration/distribution/genesis_test.go (1 hunks)
  • x/bank/keeper/keeper_test.go (21 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/integration/distribution/genesis_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/testing/environment.go
🧰 Additional context used
📓 Path-based instructions (2)
core/testing/context.go (1)

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

x/bank/keeper/keeper_test.go (2)

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


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

🪛 GitHub Actions: Lint
core/testing/context.go

[error] 4-4: File is not gci-ed with --skip-generated -s standard -s default -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) --custom-order

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: tests (00)
  • GitHub Check: test-system-v2
  • GitHub Check: Analyze
  • GitHub Check: Summary
🔇 Additional comments (2)
core/testing/context.go (1)

14-18: LGTM! Clean implementation of TestContext.

The type definition correctly embeds context.Context and includes proper interface compliance checking.

x/bank/keeper/keeper_test.go (1)

132-140: LGTM! Good adoption of the new testing framework.

The test environment setup properly initializes the TestEnvironment with appropriate configuration and context.

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

🧹 Nitpick comments (4)
testutil/queryclient/queryclient.go (1)

68-71: Improve error handling in NewStream method.

Instead of using a panic, consider returning a proper error message indicating that streaming is not supported in the test utility.

-func (q *QueryHelper) NewStream(context.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
-  panic("not implemented")
+func (q *QueryHelper) NewStream(context.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
+  return nil, fmt.Errorf("streaming is not supported in the test query helper")
}
schema/appdata/mux.go (1)

142-142: Fix code formatting.

Remove trailing whitespace after batch.apply(&listener).

-			err := batch.apply(&listener) 
+			err := batch.apply(&listener)
🧰 Tools
🪛 golangci-lint (1.62.2)

142-142: File is not gofumpt-ed with -extra

(gofumpt)

x/bank/keeper/keeper_test.go (2)

1390-1394: Improve event testing robustness.

The test relies on magic numbers for event array indices (8 and 7). Consider creating helper functions to find specific events by type and attributes to make the tests more maintainable.

Example helper function:

func findEventByType(events []coreevent.Event, eventType string) (coreevent.Event, bool) {
    for _, event := range events {
        if event.Type == eventType {
            return event, true
        }
    }
    return coreevent.Event{}, false
}

1445-1445: Add comments explaining event counts.

The test expects specific event counts (10 and 25) but doesn't explain why these numbers are expected. Add comments explaining the event breakdown to improve test maintainability.

+// 10 events: 2 mint + 2 coin_spent + 2 coin_recv + 2 transfer + 2 message events
 events = suite.env.MemEventsService().GetEvents(suite.ctx)
 require.Equal(10, len(events))

+// 25 events: previous 10 + 3 additional funding operations (5 events each)
 events = suite.env.MemEventsService().GetEvents(suite.ctx)
 require.Equal(25, len(events))

Also applies to: 1460-1460

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d42ac1f and a6ffa04.

📒 Files selected for processing (5)
  • core/testing/context.go (2 hunks)
  • schema/appdata/mux.go (1 hunks)
  • testutil/queryclient/queryclient.go (1 hunks)
  • x/bank/keeper/grpc_query_test.go (17 hunks)
  • x/bank/keeper/keeper_test.go (21 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • x/bank/keeper/grpc_query_test.go
🧰 Additional context used
📓 Path-based instructions (4)
schema/appdata/mux.go (1)

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

core/testing/context.go (1)

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

x/bank/keeper/keeper_test.go (2)

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


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

testutil/queryclient/queryclient.go (1)

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

🪛 golangci-lint (1.62.2)
schema/appdata/mux.go

142-142: File is not gofumpt-ed with -extra

(gofumpt)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: tests (00)
  • GitHub Check: test-system-v2
  • GitHub Check: Analyze
  • GitHub Check: Summary
🔇 Additional comments (1)
core/testing/context.go (1)

15-19: LGTM! Well-structured context wrapper.

The TestContext implementation is clean and follows good practices with proper interface checks and clear method documentation.

testutil/queryclient/queryclient.go Outdated Show resolved Hide resolved
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

🧹 Nitpick comments (5)
core/testing/event.go (1)

16-21: Consider adding validation for empty moduleName.

While the implementation is correct, it might be worth adding validation to prevent empty module names.

 func NewTestEventService(ctx context.Context, moduleName string) TestEventService {
+    if moduleName == "" {
+        panic("moduleName cannot be empty")
+    }
     unwrap(ctx).events[moduleName] = nil
     unwrap(ctx).protoEvents[moduleName] = nil
     return TestEventService{moduleName: moduleName}
 }
core/testing/transaction.go (1)

13-17: Consider documenting the default ExecMode behavior.

While the implementation is correct, it would be helpful to document the default execution mode behavior for test scenarios.

+// ExecMode returns the execution mode from the test context.
+// By default, it returns the mode set in the dummy context.
 func (m TestTransactionService) ExecMode(ctx context.Context) transaction.ExecMode {
     dummy := unwrap(ctx)
     return dummy.execMode
 }
core/testing/gas.go (1)

13-23: Consider adding panic recovery for unwrap failures.

The implementation is correct, but it might be worth adding panic recovery when unwrapping fails to provide better error messages in tests.

 func (m TestGasService) GasMeter(ctx context.Context) gas.Meter {
+    defer func() {
+        if r := recover(); r != nil {
+            panic(fmt.Sprintf("failed to get gas meter: %v", r))
+        }
+    }()
     dummy := unwrap(ctx)
     return dummy.gasMeter
 }
core/testing/environment.go (1)

36-38: Document nil service implications.

Some services are explicitly set to nil. Consider documenting the implications of these nil services for test scenarios.

 type TestEnvironment struct {
     appmodulev2.Environment
+    // testEventService and testHeaderService are concrete implementations
+    // that provide additional testing capabilities
     testEventService  TestEventService
     testHeaderService TestHeaderService
 }

Also applies to: 44-44

core/testing/router.go (1)

85-92: Consider documenting non-deterministic behavior.

The map iteration in the Build method may produce non-deterministic results. While this is acceptable in test code, it should be documented to avoid confusion.

Add a comment like:

+// Note: The order of handler registration is non-deterministic due to map iteration.
 for msgType, handler := range b.handlers {
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6ffa04 and e18d809.

📒 Files selected for processing (9)
  • core/testing/environment.go (1 hunks)
  • core/testing/event.go (1 hunks)
  • core/testing/gas.go (1 hunks)
  • core/testing/header.go (1 hunks)
  • core/testing/router.go (1 hunks)
  • core/testing/transaction.go (1 hunks)
  • schema/appdata/mux.go (1 hunks)
  • testutil/queryclient/queryclient.go (1 hunks)
  • x/bank/keeper/keeper_test.go (21 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/testing/header.go
  • testutil/queryclient/queryclient.go
🧰 Additional context used
📓 Path-based instructions (7)
core/testing/transaction.go (1)

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

core/testing/gas.go (1)

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

core/testing/environment.go (1)

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

core/testing/event.go (1)

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

x/bank/keeper/keeper_test.go (2)

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


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

core/testing/router.go (1)

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

schema/appdata/mux.go (1)

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

🪛 golangci-lint (1.62.2)
schema/appdata/mux.go

[medium] 142-142: G601: Implicit memory aliasing in for loop.

(gosec)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: tests (00)
  • GitHub Check: test-system-v2
  • GitHub Check: Analyze
  • GitHub Check: Summary
🔇 Additional comments (10)
core/testing/event.go (2)

12-14: LGTM! Clean and focused type definition.

The TestEventService type is well-defined with a clear purpose and minimal state.


24-33: LGTM! Methods are concise and follow interface contract.

The implementation of EventManager, GetEvents, and GetProtoEvents is clean and follows the interface contract correctly.

core/testing/transaction.go (1)

9-11: LGTM! Clean interface implementation.

The type definition and interface compliance check are well-structured.

core/testing/gas.go (1)

9-11: LGTM! Clean interface implementation.

The type definition and interface compliance check are well-structured.

core/testing/environment.go (3)

13-25: LGTM! Well-structured configuration types.

The configuration and environment types are well-defined with clear separation of concerns.


55-65: LGTM! Clean service accessor methods.

The service accessor methods are well-implemented and provide clear access to the underlying services.


27-53: 🛠️ Refactor suggestion

Consider alternatives to context.WithValue for environment storage.

As noted in previous reviews, using context.WithValue can obscure type checking. Consider alternative approaches to store the environment reference.

 type TestContext struct {
     context.Context
+    environment appmodulev2.Environment
 }

 func NewTestEnvironment(cfg TestEnvironmentConfig) (TestContext, TestEnvironment) {
     ctx := Context()
     // ... existing setup code ...
-    ctx.Context = context.WithValue(ctx.Context, corecontext.EnvironmentContextKey, env.Environment)
+    ctx.environment = env.Environment
     return ctx, env
 }

Likely invalid or redundant comment.

core/testing/router.go (1)

16-23: LGTM! Well-structured router implementation.

The router implementation follows good practices with proper initialization and error handling.

x/bank/keeper/keeper_test.go (2)

1390-1394: LGTM! Event handling is properly updated.

The event handling is correctly migrated to use the new environment service.


133-141: LGTM! Test environment setup is well-structured.

The test environment configuration and initialization is properly implemented using the new coretesting package.

@@ -139,7 +139,7 @@ func ListenerMux(listeners ...Listener) Listener {

mux.onBatch = func(batch PacketBatch) error {
for _, listener := range listeners {
err := batch.apply(&listener) //nolint:gosec // aliasing is safe here
err := batch.apply(&listener)
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

Address potential memory aliasing in loop iteration.

The loop variable listener is being passed by reference to batch.apply, which could lead to unexpected behavior if the batch processing modifies the listener state.

Apply this diff to create a local copy of the listener:

-err := batch.apply(&listener)
+listenerCopy := listener
+err := batch.apply(&listenerCopy)
📝 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
err := batch.apply(&listener)
listenerCopy := listener
err := batch.apply(&listenerCopy)
🧰 Tools
🪛 golangci-lint (1.62.2)

[medium] 142-142: G601: Implicit memory aliasing in for loop.

(gosec)

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: 0

🧹 Nitpick comments (6)
x/bank/keeper/keeper_test.go (6)

154-162: LGTM! Consider adding environment validation.

The test environment setup looks good and aligns with the new testing framework. The configuration and initialization are properly structured.

Consider adding validation for required environment fields before initialization:

 testEnironmentConfig := coretesting.TestEnvironmentConfig{
   ModuleName:  banktypes.ModuleName,
   Logger:      log.NewNopLogger(),
   MsgRouter:   nil,
   QueryRouter: nil,
+  // Add validation
+  if testEnironmentConfig.ModuleName == "" {
+    return nil, nil, fmt.Errorf("module name is required")
+  }
 }

1411-1415: Improve test readability by explaining the event count.

The magic number 8 in the event count check makes it difficult to understand why exactly 8 events are expected.

Consider adding a comment explaining the event breakdown or use constants:

+// Expected events:
+// 1. EventTypeMint from funding
+// 2-7. EventTypeCoinSpent and EventTypeCoinReceived from funding
+// 8. EventTypeTransfer from the actual transfer
 require.Equal(8, len(events))

Line range hint 1456-1466: Improve consistency in event count handling.

The test uses magic numbers (10, 25) for event count verification without explaining the breakdown of expected events.

Consider using constants or helper functions to make the event count expectations more maintainable:

+const (
+  baseEventCount = 3 // mint + coin_spent + coin_recv
+  fundingEventCount = baseEventCount * 3 // for 3 funding operations
+  transferEventCount = 1
+)
+
-require.Equal(10, len(events))
+require.Equal(baseEventCount*3 + transferEventCount, len(events))

Also applies to: 1481-1481


1572-1572: Clarify context handling in test.

The comment about context reassignment could be more explicit about why it's necessary.

Consider adding a more descriptive comment:

-// Go back to the suite's context since mockFundAccount uses that; FundAccount would fail for bad mocking otherwise.
+// Reset to suite's context to ensure consistent mocking behavior.
+// mockFundAccount expects the suite's context for proper mock setup,
+// and FundAccount would fail with the modified context.
 ctx = suite.ctx

1734-1734: Consider using explicit time handling.

The test relies on the environment's header time, which is good for consistency but could be more explicit.

Consider using a helper function for time-related test setup:

+func (suite *KeeperTestSuite) getTestTime() time.Time {
+  return suite.env.HeaderService().HeaderInfo(suite.ctx).Time
+}
+
-vacc, err := vesting.NewContinuousVestingAccount(acc0, origCoins, suite.env.HeaderService().HeaderInfo(suite.ctx).Time.Unix(), endTime.Unix())
+vacc, err := vesting.NewContinuousVestingAccount(acc0, origCoins, suite.getTestTime().Unix(), endTime.Unix())

136-137: Consider adding specific tests for TestContext and TestEnvironment.

While the existing tests implicitly verify the new testing framework, explicit tests would be valuable.

Consider adding dedicated test cases:

func (suite *KeeperTestSuite) TestEnvironmentSetup() {
    require := suite.Require()
    
    // Test environment initialization
    require.NotNil(suite.env)
    require.Equal(banktypes.ModuleName, suite.env.ModuleName())
    
    // Test context initialization
    require.NotNil(suite.ctx)
    require.NotZero(suite.ctx.HeaderInfo().Time)
}
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e18d809 and 4f56126.

⛔ Files ignored due to path filters (1)
  • x/bank/go.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • x/bank/go.mod (2 hunks)
  • x/bank/keeper/grpc_query_test.go (17 hunks)
  • x/bank/keeper/keeper_test.go (21 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • x/bank/go.mod
  • x/bank/keeper/grpc_query_test.go
🧰 Additional context used
📓 Path-based instructions (1)
x/bank/keeper/keeper_test.go (2)

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


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

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: tests (00)
  • GitHub Check: test-system-v2
  • GitHub Check: Analyze
  • GitHub Check: Summary

@aljo242 aljo242 enabled auto-merge January 7, 2025 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants