-
Notifications
You must be signed in to change notification settings - Fork 815
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
Add testing harness for e2e application logic tests #850
Conversation
panic(err) | ||
} | ||
_, err = a.InitChain(context.Background(), &types.RequestInitChain{ | ||
Time: time.Now(), |
Check warning
Code scanning / CodeQL
Calling the system time
Hash: []byte("abc"), // no needed for application logic | ||
Height: a.height, | ||
ProposerAddress: getValAddress(a.GetProposer()), | ||
Time: time.Now(), |
Check warning
Code scanning / CodeQL
Calling the system time
testutil/processblock/verify/dex.go
Outdated
for market := range markets { | ||
orderPlacements := []*dextypes.Order{} | ||
if o, ok := orderPlacementsByMarket[market]; ok { | ||
orderPlacements = o | ||
} | ||
orderCancellations := []*dextypes.Cancellation{} | ||
if c, ok := orderCancellationsByMarket[market]; ok { | ||
orderCancellations = c | ||
} | ||
parts := strings.Split(market, ",") | ||
longBook, shortBook := expectedOrdersForMarket(ctx, keeper, orderPlacements, orderCancellations, parts[0], parts[1], parts[2]) | ||
expectedLongBookByMarket[market] = longBook | ||
expectedShortBookByMarket[market] = shortBook | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
testutil/processblock/verify/dex.go
Outdated
for market, longBook := range expectedLongBookByMarket { | ||
parts := strings.Split(market, ",") | ||
contract := parts[0] | ||
priceDenom := parts[1] | ||
assetDenom := parts[2] | ||
require.Equal(t, len(longBook), len(keeper.GetAllLongBookForPair(ctx, contract, priceDenom, assetDenom))) | ||
for price, entry := range longBook { | ||
actual, found := keeper.GetLongOrderBookEntryByPrice(ctx, contract, price, priceDenom, assetDenom) | ||
require.True(t, found) | ||
require.Equal(t, *entry, *(actual.GetOrderEntry())) | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
testutil/processblock/verify/dex.go
Outdated
for market, shortBook := range expectedShortBookByMarket { | ||
parts := strings.Split(market, ",") | ||
contract := parts[0] | ||
priceDenom := parts[1] | ||
assetDenom := parts[2] | ||
require.Equal(t, len(shortBook), len(keeper.GetAllShortBookForPair(ctx, contract, priceDenom, assetDenom))) | ||
for price, entry := range shortBook { | ||
actual, found := keeper.GetShortOrderBookEntryByPrice(ctx, contract, price, priceDenom, assetDenom) | ||
require.True(t, found) | ||
require.Equal(t, *entry, *(actual.GetOrderEntry())) | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
22e6ac3
to
17a2ac4
Compare
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #850 +/- ##
==========================================
+ Coverage 63.41% 63.52% +0.11%
==========================================
Files 250 250
Lines 15533 15533
==========================================
+ Hits 9850 9868 +18
+ Misses 5219 5197 -22
- Partials 464 468 +4
|
for denom, changes := range expectedChanges { | ||
expectedBalances[denom] = map[string]int64{} | ||
for account, delta := range changes { | ||
balance := app.BankKeeper.GetBalance(app.Ctx(), sdk.MustAccAddressFromBech32(account), denom) | ||
expectedBalances[denom][account] = balance.Amount.Int64() + delta | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
for account, delta := range changes { | ||
balance := app.BankKeeper.GetBalance(app.Ctx(), sdk.MustAccAddressFromBech32(account), denom) | ||
expectedBalances[denom][account] = balance.Amount.Int64() + delta | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
for denom, expectedBalances := range expectedBalances { | ||
for account, expectedBalance := range expectedBalances { | ||
actualBalance := app.BankKeeper.GetBalance(app.Ctx(), sdk.MustAccAddressFromBech32(account), denom) | ||
require.Equal(t, expectedBalance, actualBalance.Amount.Int64()) | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
for account, expectedBalance := range expectedBalances { | ||
actualBalance := app.BankKeeper.GetBalance(app.Ctx(), sdk.MustAccAddressFromBech32(account), denom) | ||
require.Equal(t, expectedBalance, actualBalance.Amount.Int64()) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
for price, entry := range longBook { | ||
actual, found := app.DexKeeper.GetLongOrderBookEntryByPrice(app.Ctx(), contract, price, priceDenom, assetDenom) | ||
require.True(t, found) | ||
require.Equal(t, *entry, *(actual.GetOrderEntry())) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
for price, entry := range shortBook { | ||
actual, found := app.DexKeeper.GetShortOrderBookEntryByPrice(app.Ctx(), contract, price, priceDenom, assetDenom) | ||
require.True(t, found) | ||
require.Equal(t, *entry, *(actual.GetOrderEntry())) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
@@ -0,0 +1,84 @@ | |||
package verify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some things that might help with verification are the implicit actions that are preformed each block like:
- epoch hooks (mint events)
- fee/delegation distribution
- slashing/jailing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added verifiers and tests for epoch/mint/distribution. Slashing/jailing is a bit more complicated so I plan to add it in a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good thank you!
tests/dex_test.go
Outdated
blockRunner := func() []uint32 { return app.RunBlock(block2) } // 2nd block to place order | ||
blockRunner = verify.DexOrders(t, app, blockRunner, block2) | ||
blockRunner = verify.Balance(t, app, blockRunner, block2) | ||
|
||
require.Equal(t, []uint32{0}, blockRunner()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So when we need to apply verify methods we need to create a blockRunner variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah it's basically a wrapper around RunBlock
but with verifier chained together:
verifierA_load_pre_execution_state
verifierB_load_pre_execution_state
RunBlock
verifierB_check_post_execution_state
verifierA_check_post_execution_state
17a2ac4
to
286eff4
Compare
) | ||
|
||
func (a *App) NewMinter(amount uint64) { | ||
today := time.Now() |
Check warning
Code scanning / CodeQL
Calling the system time
for val, reward := range expectedOutstandingRewards { | ||
require.True(t, reward.Equal(actualOutstandingRewards[val])) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
tests/template_test.go
Outdated
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestTemplate(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an easy way to modify the template so that it could support the best practice golang table driven testing norm such as:
type TestCase {
description string
input Input
verifier func
expectedResult Result
}
for _, scenario := range []TestCase{
{
description: "test case1",
input: Input{},
verifier: func(){},
expectedResult: []uint32{0,0},
},
{
description: "test case2",
input: Input{},
verifier: func(){},
expectedResult: []uint32{0,1},
},
}
{
t.Run(scenario.description, func(t *testing.T) {
...
})
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yzang2019 it should be doable, but not sure if it'd be very readable given the amount of different setup needed for different tests. I'll give it a try
tests/dex_test.go
Outdated
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestOrders(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have a more specific name for the Test function instead of calling TestOrders? Basically I would like to know what are we testing for orders? Which specific logic are we verifying here, let's break it down into smaller pieces, same thing applied to other modules
0f9f7aa
to
aca206d
Compare
aca206d
to
40ee107
Compare
Describe your changes and provide context
Add a testing harness to simplify writing application-level e2e test. The goal is to allow testing the full application write path that roots from
FinalizeBlock
andCommit
, since more granular tests like ones on keeper level lack the capability to uncover bugs caused by improper interactions between modules or invalid assumptions across transactions and Begin/Mid/EndBlock logics. Specifically the harness includes:App
object, which provides simple interfaces for processing a block and transaction signing. [testutils/processblock/common.go
]testutils/processblock/genesis*.go
]testutils/processblock/msgs/*.go
]testutils/processblock/verify/*.go
]A test written using this harness typically includes three phases:
tests/template_test.go
provided a template for writing such tests, andtests/dex_test.go
is a concrete examples.Next steps:
Testing performed to validate your change
tests