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!: attempt to resolve flakes #2834

Merged
merged 31 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c3758ff
test: attempt to unflake max total blob size
rootulp Nov 10, 2023
d29f4b3
refactor: mustNewBlob -> newBlobWithSize
rootulp Nov 10, 2023
841cc14
refactor: setup accounts
rootulp Nov 10, 2023
9f7a4a8
refactor: TestMaxBlockSize
rootulp Nov 10, 2023
c0e908d
refactor: remove redundant continue
rootulp Nov 10, 2023
cb7d883
refactor: remove unnecessary verification
rootulp Nov 10, 2023
9123e69
refactor: collapse vertically
rootulp Nov 10, 2023
c08a962
refactor: rename to ExtendBlockTest
rootulp Nov 10, 2023
18a9632
refactor: use sizes
rootulp Nov 10, 2023
bf93ad2
refactor: extract RandomAccounts()
rootulp Nov 10, 2023
d17de92
refactor: rename tests
rootulp Nov 10, 2023
50e3282
refactor: rename test
rootulp Nov 10, 2023
2a2cd22
refactor: remove _flaky
rootulp Nov 10, 2023
0369f21
test: attempt to differentiate accounts per test
rootulp Nov 10, 2023
4ed02a5
test: remove _flaky suffix
rootulp Nov 10, 2023
278fc27
refactor: units
rootulp Nov 25, 2023
cf47f2e
test: remove redundant test cases
rootulp Nov 25, 2023
d625910
refactor: use units
rootulp Nov 25, 2023
e3a9a23
test: delete submit PFB
rootulp Nov 25, 2023
0a3eb0a
refactor: extract shared units
rootulp Nov 25, 2023
ee5d427
remove redundant tests
rootulp Nov 25, 2023
2c0273f
refactor: unexport unit
rootulp Nov 25, 2023
9b3db74
Merge branch 'main' into rp/refactor-test
rootulp Nov 25, 2023
39ea848
ci: debug lint failure
rootulp Nov 25, 2023
39148f6
attempt to fix lint
rootulp Nov 25, 2023
8da4fa5
chore: prefer context.Background()
rootulp Nov 25, 2023
1447745
refactor: rename test
rootulp Nov 27, 2023
f427908
refactor: remove ErrTxTooLarge test case
rootulp Nov 27, 2023
efcb52d
refactor: delete test entirely
rootulp Nov 27, 2023
3e0c902
test: new test case for square construction
rootulp Nov 27, 2023
4a9d8e5
revert: network -> net
rootulp Nov 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/test/block_production_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package app
package app_test

import (
"testing"
Expand Down
162 changes: 30 additions & 132 deletions app/test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/celestiaorg/celestia-app/pkg/user"
blobtypes "github.com/celestiaorg/celestia-app/x/blob/types"

sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
tmrand "github.com/tendermint/tendermint/libs/rand"
coretypes "github.com/tendermint/tendermint/types"
Expand All @@ -54,12 +53,7 @@ type IntegrationTestSuite struct {

func (s *IntegrationTestSuite) SetupSuite() {
t := s.T()

numAccounts := 142
s.accounts = make([]string, numAccounts)
for i := 0; i < numAccounts; i++ {
s.accounts[i] = tmrand.Str(20)
}
s.accounts = testnode.RandomAccounts(142)

cfg := testnode.DefaultConfig().WithFundedAccounts(s.accounts...)

Expand All @@ -80,47 +74,41 @@ func (s *IntegrationTestSuite) SetupSuite() {
func (s *IntegrationTestSuite) TestMaxBlockSize() {
t := s.T()

// tendermint's default tx size limit is 1Mb, so we get close to that
Copy link
Collaborator

Choose a reason for hiding this comment

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

[Question] Shouldn't this be revised instead of removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The comment is no longer accurate b/c now this tx generator creates transactions that are ~600 KiB

equallySized1MbTxGen := func(c client.Context) []coretypes.Tx {
singleBlobTxGen := func(c client.Context) []coretypes.Tx {
return blobfactory.RandBlobTxsWithAccounts(
s.ecfg,
tmrand.NewRand(),
s.cctx.Keyring,
c.GRPCClient,
950000,
600*kibibyte,
Copy link
Collaborator

Choose a reason for hiding this comment

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

[Question] Curious to know why this change was needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This change wasn't strictly needed. I thought it was misleading that the variable name stated 1Mb when the generator created transactions that weren't 1Mb. Opted to change the variable name and the size of txs created.

1,
false,
s.accounts[:20],
)
}
rootulp marked this conversation as resolved.
Show resolved Hide resolved

// Tendermint's default tx size limit is 1 MiB, so we get close to that by
// generating transactions of size 600 KB because 3 blobs per transaction *
// 200,000 bytes each = 600,000 total bytes = 600 KB per transaction.
randMultiBlob1MbTxGen := func(c client.Context) []coretypes.Tx {
// This tx generator generates txs that contain 3 blobs each of 200 KiB so
// 600 KiB total per transaction.
multiBlobTxGen := func(c client.Context) []coretypes.Tx {
return blobfactory.RandBlobTxsWithAccounts(
s.ecfg,
tmrand.NewRand(),
s.cctx.Keyring,
c.GRPCClient,
200000, // 200 KB
200*kibibyte,
3,
false,
s.accounts[20:40],
)
}

// Generate 80 randomly sized txs (max size == 50 KB). Generate these
Copy link
Collaborator

Choose a reason for hiding this comment

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

[Question] Are these comments removed intentionally?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes.

Generate these transactions using some of the same accounts as the previous generator to ensure that the sequence number is being utilized correctly in blob txs

was incorrect because this tx generator used accounts 40 - 120 which does not overlap with the previous tx generator (20 - 40). So I deleted the misleading comment.

// transactions using some of the same accounts as the previous generator to
// ensure that the sequence number is being utilized correctly in blob
// txs
randoTxGen := func(c client.Context) []coretypes.Tx {
randomTxGen := func(c client.Context) []coretypes.Tx {
return blobfactory.RandBlobTxsWithAccounts(
s.ecfg,
tmrand.NewRand(),
s.cctx.Keyring,
c.GRPCClient,
50000,
50*kibibyte,
8,
true,
s.accounts[40:120],
Expand All @@ -131,27 +119,21 @@ func (s *IntegrationTestSuite) TestMaxBlockSize() {
name string
txGenerator func(clientCtx client.Context) []coretypes.Tx
}

tests := []test{
{
"20 1Mb txs",
equallySized1MbTxGen,
},
{
"20 1Mb multiblob txs",
randMultiBlob1MbTxGen,
},
{
"80 random txs",
randoTxGen,
},
{"singleBlobTxGen", singleBlobTxGen},
{"multiBlobTxGen", multiBlobTxGen},
{"randomTxGen", randomTxGen},
}
for _, tc := range tests {
s.Run(tc.name, func() {
txs := tc.txGenerator(s.cctx.Context)
hashes := make([]string, len(txs))

for i, tx := range txs {
// The default CometBFT mempool MaxTxBytes is 1 MiB so the generators in
// this test must create transactions that are smaller than that.
require.LessOrEqual(t, len(tx), 1*mebibyte)

res, err := s.cctx.Context.BroadcastTxSync(tx)
require.NoError(t, err)
assert.Equal(t, abci.CodeTypeOK, res.Code, res.RawLog)
rootulp marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -167,10 +149,7 @@ func (s *IntegrationTestSuite) TestMaxBlockSize() {
for _, hash := range hashes {
resp, err := testnode.QueryTx(s.cctx.Context, hash, true)
require.NoError(t, err)
assert.NotNil(t, resp)
if resp == nil {
continue
}
require.NotNil(t, resp)
require.Equal(t, abci.CodeTypeOK, resp.TxResult.Code, resp.TxResult.Log)
heights[resp.Height]++
// ensure that some gas was used
rootulp marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -195,7 +174,7 @@ func (s *IntegrationTestSuite) TestMaxBlockSize() {
require.EqualValues(t, v2.Version, blockRes.Block.Header.Version.App)

sizes = append(sizes, size)
ExtendBlobTest(t, blockRes.Block)
ExtendBlockTest(t, blockRes.Block)
}
// ensure that at least one of the blocks used the max square size
assert.Contains(t, sizes, uint64(appconsts.DefaultGovMaxSquareSize))
rootulp marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -204,71 +183,6 @@ func (s *IntegrationTestSuite) TestMaxBlockSize() {
}
}

func (s *IntegrationTestSuite) TestSubmitPayForBlob() {
rootulp marked this conversation as resolved.
Show resolved Hide resolved
t := s.T()
ns1 := appns.MustNewV0(bytes.Repeat([]byte{1}, appns.NamespaceVersionZeroIDSize))

mustNewBlob := func(ns appns.Namespace, data []byte, shareVersion uint8) *blob.Blob {
return blob.New(ns, data, shareVersion)
}

type test struct {
name string
blob *blob.Blob
opts []user.TxOption
}

tests := []test{
{
"small random typical",
mustNewBlob(ns1, tmrand.Bytes(3000), appconsts.ShareVersionZero),
[]user.TxOption{
user.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(1)))),
user.SetGasLimit(1_000_000_000),
},
},
{
"large random typical",
mustNewBlob(ns1, tmrand.Bytes(350000), appconsts.ShareVersionZero),
[]user.TxOption{
user.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))),
user.SetGasLimit(1_000_000_000),
},
},
{
"medium random with memo",
mustNewBlob(ns1, tmrand.Bytes(100000), appconsts.ShareVersionZero),
[]user.TxOption{
user.SetMemo("lol I could stick the rollup block here if I wanted to"),
user.SetGasLimit(1_000_000_000),
},
},
{
"medium random with timeout height",
mustNewBlob(ns1, tmrand.Bytes(100000), appconsts.ShareVersionZero),
[]user.TxOption{
user.SetTimeoutHeight(10000),
user.SetGasLimit(1_000_000_000),
},
},
}
for _, tc := range tests {
s.Run(tc.name, func() {
// occasionally this test will error that the mempool is full (code
// 20) so we wait a few blocks for the txs to clear
require.NoError(t, s.cctx.WaitForBlocks(3))

addr := testfactory.GetAddress(s.cctx.Keyring, s.accounts[141])
signer, err := user.SetupSigner(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, addr, s.ecfg)
require.NoError(t, err)
res, err := signer.SubmitPayForBlob(context.TODO(), []*blob.Blob{tc.blob, tc.blob}, tc.opts...)
require.NoError(t, err)
require.NotNil(t, res)
require.Equal(t, abci.CodeTypeOK, res.Code, res.Logs)
})
}
}

func (s *IntegrationTestSuite) TestUnwrappedPFBRejection() {
t := s.T()

Expand All @@ -294,13 +208,12 @@ func (s *IntegrationTestSuite) TestUnwrappedPFBRejection() {
func (s *IntegrationTestSuite) TestShareInclusionProof() {
t := s.T()

// generate 100 randomly sized txs (max size == 100kb)
txs := blobfactory.RandBlobTxsWithAccounts(
s.ecfg,
tmrand.NewRand(),
s.cctx.Keyring,
s.cctx.GRPCClient,
100000,
100*kibibyte,
1,
true,
s.accounts[120:140],
Expand Down Expand Up @@ -348,9 +261,9 @@ func (s *IntegrationTestSuite) TestShareInclusionProof() {
}
}

// ExtendBlobTest re-extends the block and compares the data roots to ensure
// ExtendBlockTest re-extends the block and compares the data roots to ensure
// that the public functions for extending the block are working correctly.
func ExtendBlobTest(t *testing.T, block *coretypes.Block) {
func ExtendBlockTest(t *testing.T, block *coretypes.Block) {
eds, err := app.ExtendBlock(block.Data, block.Header.Version.App)
require.NoError(t, err)
dah, err := da.NewDataAvailabilityHeader(eds)
Expand All @@ -370,7 +283,7 @@ func (s *IntegrationTestSuite) TestEmptyBlock() {
blockRes, err := s.cctx.Client.Block(s.cctx.GoContext(), &h)
require.NoError(t, err)
require.True(t, app.IsEmptyBlock(blockRes.Block.Data, blockRes.Block.Header.Version.App))
ExtendBlobTest(t, blockRes.Block)
ExtendBlockTest(t, blockRes.Block)
}
}

Expand All @@ -391,35 +304,20 @@ func (s *IntegrationTestSuite) TestSubmitPayForBlob_blobSizes() {
}
testCases := []testCase{
{
name: "1,000 byte blob",
blob: mustNewBlob(1_000),
txResponseCode: abci.CodeTypeOK,
},
{
name: "10,000 byte blob",
blob: mustNewBlob(10_000),
txResponseCode: abci.CodeTypeOK,
},
{
name: "100,000 byte blob",
blob: mustNewBlob(100_000),
txResponseCode: abci.CodeTypeOK,
},
{
name: "1,000,000 byte blob",
blob: mustNewBlob(1_000_000),
rootulp marked this conversation as resolved.
Show resolved Hide resolved
name: "1 mebibyte blob",
blob: newBlobWithSize(1 * mebibyte),
txResponseCode: abci.CodeTypeOK,
},
{
name: "10,000,000 byte blob returns err tx too large",
blob: mustNewBlob(10_000_000),
blob: newBlobWithSize(10_000_000),
txResponseCode: errors.ErrTxTooLarge.ABCICode(),
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), 30*time.Second)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), 60*time.Second)
defer cancel()
res, err := signer.SubmitPayForBlob(subCtx, []*blob.Blob{tc.blob}, user.SetGasLimit(1_000_000_000))
if tc.txResponseCode == abci.CodeTypeOK {
Expand All @@ -433,8 +331,8 @@ func (s *IntegrationTestSuite) TestSubmitPayForBlob_blobSizes() {
}
}

func mustNewBlob(blobSize int) *blob.Blob {
ns1 := appns.MustNewV0(bytes.Repeat([]byte{1}, appns.NamespaceVersionZeroIDSize))
data := tmrand.Bytes(blobSize)
return blob.New(ns1, data, appconsts.ShareVersionZero)
func newBlobWithSize(size int) *blob.Blob {
ns := appns.MustNewV0(bytes.Repeat([]byte{1}, appns.NamespaceVersionZeroIDSize))
data := tmrand.Bytes(size)
return blob.New(ns, data, appconsts.ShareVersionZero)
}
33 changes: 4 additions & 29 deletions app/test/max_total_blob_size_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,17 @@

"github.com/celestiaorg/celestia-app/app"
"github.com/celestiaorg/celestia-app/app/encoding"
"github.com/celestiaorg/celestia-app/pkg/appconsts"
"github.com/celestiaorg/celestia-app/pkg/blob"
"github.com/celestiaorg/celestia-app/pkg/square"
"github.com/celestiaorg/celestia-app/pkg/user"
"github.com/celestiaorg/celestia-app/test/util/testfactory"
"github.com/celestiaorg/celestia-app/test/util/testnode"
blobtypes "github.com/celestiaorg/celestia-app/x/blob/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
)

const (
mebibyte = 1_048_576 // one mebibyte in bytes
squareSize = 64

Check failure on line 20 in app/test/max_total_blob_size_test.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

const `squareSize` is unused (unused)
)

func TestMaxTotalBlobSizeSuite(t *testing.T) {
Expand Down Expand Up @@ -63,9 +58,9 @@
require.NoError(t, cctx.WaitForNextBlock())
}

// TestSubmitPayForBlob_blobSizes verifies the tx response ABCI code when
// SubmitPayForBlob is invoked with different blob sizes.
func (s *MaxTotalBlobSizeSuite) TestSubmitPayForBlob_blobSizes() {
// TestErrTotalBlobSizeTooLarge verifies that submitting a 2 MiB blob hits
// ErrTotalBlobSizeTooLarge.
func (s *MaxTotalBlobSizeSuite) TestErrTotalBlobSizeTooLarge() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

seems less flaky

$ go test -count=5 . -run "TestMaxTotalBlobSizeSuite"
ok  	github.com/celestiaorg/celestia-app/app/test	31.621s

t := s.T()

type testCase struct {
Expand All @@ -75,19 +70,9 @@
want uint32
}
testCases := []testCase{
{
name: "1 byte blob",
blob: mustNewBlob(1),
want: abci.CodeTypeOK,
},
{
name: "1 mebibyte blob",
blob: mustNewBlob(mebibyte),
want: abci.CodeTypeOK,
},
{
name: "2 mebibyte blob",
blob: mustNewBlob(2 * mebibyte),
blob: newBlobWithSize(2 * mebibyte),
want: blobtypes.ErrTotalBlobSizeTooLarge.ABCICode(),
},
Comment on lines 69 to 73
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It seems like the multiple test cases of this test are affecting each other. Since the first two test cases aren't expected to encounter an error and that happy path is covered in other tests, proposal to drop them from this test.

}
Expand All @@ -105,16 +90,6 @@
require.NoError(t, err)
require.NotNil(t, res)
require.Equal(t, tc.want, res.Code, res.Logs)

sq, err := square.Construct([][]byte{blobTx}, appconsts.LatestVersion, squareSize)
if tc.want == abci.CodeTypeOK {
// verify that if the tx was accepted, the blob can fit in a square
assert.NoError(t, err)
assert.False(t, sq.IsEmpty())
} else {
// verify that if the tx was rejected, the blob can not fit in a square
assert.Error(t, err)
rootulp marked this conversation as resolved.
Show resolved Hide resolved
}
})
}
}
3 changes: 1 addition & 2 deletions app/test/square_size_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ func (s *SquareSizeIntegrationTest) SetupSuite() {

// TestSquareSizeUpperBound sets the app's params to specific sizes, then fills the
// block with spam txs to measure that the desired max is getting hit
// The "_Flaky" suffix indicates that the test may fail non-deterministically especially when executed in CI.
func (s *SquareSizeIntegrationTest) TestSquareSizeUpperBound_Flaky() {
func (s *SquareSizeIntegrationTest) TestSquareSizeUpperBound() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

can't get it to fail locally but we should explore making this test faster

$ go test -count=1 . -run "TestSquareSizeIntegrationTest"
ok  	github.com/celestiaorg/celestia-app/app/test	106.361s

t := s.T()

type test struct {
Expand Down
6 changes: 6 additions & 0 deletions app/test/unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package app_test

const (
kibibyte = 1024
mebibyte = 1024 * kibibyte
Comment on lines +4 to +5
Copy link
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] For improved reusability and maintainability, all such unit converter constants could be consolidated into a single location.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Created #2873

)
Loading
Loading