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 18 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 context and environment management
    • Improved service interfaces for gas, header, transaction, and routing in testing scenarios
  • Improvements

    • Streamlined context handling across multiple testing components
    • Updated module and keeper tests to use new testing infrastructure
    • Simplified handler registration for message and query routers
  • Testing

    • Introduced comprehensive mock services for testing
    • Added reflection-based router for flexible handler management
    • Improved context configuration in test environments

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 comprehensive testing framework for the Cosmos SDK, focusing on enhancing context management and service mocking. The changes primarily revolve around creating a new coretesting package that provides robust testing utilities across various modules. The implementation includes a new TestContext type, memory services for different components like headers, gas, and transactions, and a reflection-based router for handling message routing during tests.

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
x/bank/keeper/*_test.go Updated test suites to use new testing framework and context

Sequence Diagram

sequenceDiagram
    participant TestEnvironment
    participant TestContext
    participant MemServices
    
    TestEnvironment->>TestContext: Create with configuration
    TestContext->>MemServices: Initialize gas, header, transaction services
    TestContext-->>TestEnvironment: Return configured context
Loading

Possibly related PRs

Suggested labels

C:server/v2, C:x/accounts

Suggested reviewers

  • facundomedica
  • kocubinski
  • julienrbrt
  • tac0turtle
  • testinginprod
  • sontrinh16

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
}
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

Store environment references without using context.WithValue.

While adding the environment to the standard context.Context is a valid pattern, it can obscure type checking and degrade readability. Instead, consider storing appmodulev2.Environment in a well-typed field of TestContext or passing it directly as needed to reduce reliance on context.WithValue.

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)
}

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.

5 participants