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

Load test runner implementation #194

Merged
merged 35 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b2328fc
Load test runner implementation
goran-ethernal Apr 10, 2024
6cc0251
UTs build fix
goran-ethernal Apr 10, 2024
88a6119
Lint fix
goran-ethernal Apr 10, 2024
b29f4a5
load-test command
goran-ethernal Apr 10, 2024
49f023d
Better UX
goran-ethernal Apr 10, 2024
0d53c02
add ZexCoin to test artifacts
goran-ethernal Apr 10, 2024
d409afe
add erc20 test name log
goran-ethernal Apr 10, 2024
96c8143
gas price increase
goran-ethernal Apr 10, 2024
1a8ae5d
collect all errors for tx sending and just log them
goran-ethernal Apr 10, 2024
5e24ea9
stale sequence check (temp fix)
goran-ethernal Apr 10, 2024
1a8b741
more gasPrice increase
goran-ethernal Apr 10, 2024
5b8321a
gather receipt errors and print them
goran-ethernal Apr 10, 2024
92b01a3
lint fix
goran-ethernal Apr 10, 2024
71bd46c
feeData
goran-ethernal Apr 10, 2024
29a9191
Lint fix
goran-ethernal Apr 11, 2024
395ea07
fix
goran-ethernal Apr 11, 2024
fb2b4f1
ERC721 support
goran-ethernal Apr 11, 2024
a825254
results to json file
goran-ethernal Apr 11, 2024
78722ab
lint fix
goran-ethernal Apr 11, 2024
8001d83
remove comment
goran-ethernal Apr 11, 2024
82c1ad3
receipts gather in separate routines
goran-ethernal Apr 11, 2024
5da6111
remove receipts timeout from fund and deploy functions
goran-ethernal Apr 12, 2024
49d98f6
ticker timeout and gasPrice increase
goran-ethernal Apr 12, 2024
0eeb26f
lock in gathering receipts
goran-ethernal Apr 12, 2024
c360cf9
increase maxDemotionsNum
goran-ethernal Apr 12, 2024
d99c537
waitForTxPool flag, and gathering results in parallel
goran-ethernal Apr 14, 2024
c3f370d
lint fix
goran-ethernal Apr 14, 2024
01c519e
fix ut
goran-ethernal Apr 15, 2024
b5d7889
Merge commit '5d6017f91bb6ea4e5cff7f0c4bf18a8c13a3a29f' into Load-tes…
goran-ethernal Apr 15, 2024
f37b506
Go mod tidy
Stefan-Ethernal Apr 15, 2024
b51efd8
comments fix
goran-ethernal Apr 15, 2024
ba5fd1f
lint fix
goran-ethernal Apr 15, 2024
48e6db1
more statistics
goran-ethernal Apr 15, 2024
bbe13f5
small fix
goran-ethernal Apr 15, 2024
47e9d16
small fix
goran-ethernal Apr 15, 2024
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
23 changes: 21 additions & 2 deletions command/bridge/fund/fund.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/0xPolygon/polygon-edge/command/bridge/helper"
cmdHelper "github.com/0xPolygon/polygon-edge/command/helper"
polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init"
"github.com/0xPolygon/polygon-edge/jsonrpc"
"github.com/0xPolygon/polygon-edge/txrelayer"
"github.com/0xPolygon/polygon-edge/types"
)
Expand Down Expand Up @@ -78,8 +79,18 @@ func runCommand(cmd *cobra.Command, _ []string) {
outputter := command.InitializeOutputter(cmd)
defer outputter.WriteOutput()

txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress),
txrelayer.WithReceiptsTimeout(params.txTimeout))
client, err := jsonrpc.NewEthClient(params.jsonRPCAddress)
if err != nil {
outputter.SetError(fmt.Errorf("failed to initialize eth client: %w", err))

return
}

txRelayer, err := txrelayer.NewTxRelayer(
txrelayer.WithClient(client),
txrelayer.WithReceiptsTimeout(params.txTimeout),
txrelayer.WithoutNonceGet(),
)
if err != nil {
outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err))

Expand All @@ -93,6 +104,13 @@ func runCommand(cmd *cobra.Command, _ []string) {
return
}

senderNonce, err := client.GetNonce(deployerKey.Address(), jsonrpc.PendingBlockNumberOrHash)
if err != nil {
outputter.SetError(fmt.Errorf("failed to get deployer nonce: %w", err))

return
}

results := make([]command.CommandResult, len(params.addresses))
g, ctx := errgroup.WithContext(cmd.Context())

Expand All @@ -107,6 +125,7 @@ func runCommand(cmd *cobra.Command, _ []string) {
default:
fundAddr := params.addresses[i]
txn := helper.CreateTransaction(types.ZeroAddress, &fundAddr, nil, params.amountValues[i], true)
txn.SetNonce(senderNonce + uint64(i))

var (
receipt *ethgo.Receipt
Expand Down
127 changes: 127 additions & 0 deletions command/loadtest/load_test_run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package loadtest

import (
"time"

"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/loadtest/runner"
"github.com/spf13/cobra"
)

var (
params loadTestParams
)

func GetCommand() *cobra.Command {
loadTestCmd := &cobra.Command{
Use: "load-test",
Short: "Runs a load test on a specified network",
PreRunE: preRunCommand,
Run: runCommand,
}

helper.RegisterJSONRPCFlag(loadTestCmd)

setFlags(loadTestCmd)

return loadTestCmd
}

func preRunCommand(cmd *cobra.Command, _ []string) error {
params.jsonRPCAddress = helper.GetJSONRPCAddress(cmd)

return params.validateFlags()
}

func setFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
&params.mnemonic,
mnemonicFlag,
"",
"the mnemonic used to generate and fund virtual users",
)

cmd.Flags().StringVar(
&params.loadTestType,
loadTestTypeFlag,
"eoa",
"the type of load test to run (supported types: eoa, erc20, erc721)",
)

cmd.Flags().StringVar(
&params.loadTestName,
loadTestNameFlag,
"load test",
"the name of the load test",
)

cmd.Flags().IntVar(
&params.vus,
vusFlag,
1,
"the number of virtual users",
)

cmd.Flags().IntVar(
&params.txsPerUser,
txsPerUserFlag,
1,
"the number of transactions per virtual user",
)

cmd.Flags().BoolVar(
&params.dynamicTxs,
dynamicTxsFlag,
false,
"indicates whether the load test should generate dynamic transactions",
)

cmd.Flags().DurationVar(
&params.receiptsTimeout,
receiptsTimeoutFlag,
30*time.Second,
"the timeout for waiting for transaction receipts",
)

cmd.Flags().DurationVar(
&params.txPoolTimeout,
txPoolTimeoutFlag,
10*time.Minute,
"the timeout for waiting for the transaction pool to empty",
)

cmd.Flags().BoolVar(
&params.toJSON,
saveToJSONFlag,
false,
"saves results to JSON file",
)

_ = cmd.MarkFlagRequired(mnemonicFlag)
_ = cmd.MarkFlagRequired(loadTestTypeFlag)
}

func runCommand(cmd *cobra.Command, _ []string) {
outputter := command.InitializeOutputter(cmd)
defer outputter.WriteOutput()

loadTestRunner := &runner.LoadTestRunner{}

err := loadTestRunner.Run(runner.LoadTestConfig{
Mnemonnic: params.mnemonic,
LoadTestType: params.loadTestType,
LoadTestName: params.loadTestName,
JSONRPCUrl: params.jsonRPCAddress,
ReceiptsTimeout: params.receiptsTimeout,
TxPoolTimeout: params.txPoolTimeout,
VUs: params.vus,
TxsPerUser: params.txsPerUser,
DynamicTxs: params.dynamicTxs,
ResultsToJSON: params.toJSON,
})

if err != nil {
outputter.SetError(err)
}
}
70 changes: 70 additions & 0 deletions command/loadtest/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package loadtest

import (
"errors"
"time"

"github.com/0xPolygon/polygon-edge/loadtest/runner"
)

const (
mnemonicFlag = "mnemonic"
loadTestTypeFlag = "type"
loadTestNameFlag = "name"

receiptsTimeoutFlag = "receipts-timeout"
txPoolTimeoutFlag = "txpool-timeout"

vusFlag = "vus"
txsPerUserFlag = "txs-per-user"
dynamicTxsFlag = "dynamic"

saveToJSONFlag = "to-json"
)

var (
errNoMnemonicProvided = errors.New("no mnemonic provided")
errNoLoadTestTypeProvided = errors.New("no load test type provided")
errUnsupportedLoadTestType = errors.New("unsupported load test type")
errInvalidVUs = errors.New("vus must be greater than 0")
errInvalidTxsPerUser = errors.New("txs-per-user must be greater than 0")
)

type loadTestParams struct {
mnemonic string
loadTestType string
loadTestName string

jsonRPCAddress string
receiptsTimeout time.Duration
txPoolTimeout time.Duration

vus int
txsPerUser int
dynamicTxs bool
toJSON bool
}

func (ltp *loadTestParams) validateFlags() error {
if ltp.mnemonic == "" {
return errNoMnemonicProvided
}

if ltp.loadTestType == "" {
return errNoLoadTestTypeProvided
}

if !runner.IsLoadTestSupported(ltp.loadTestType) {
return errUnsupportedLoadTestType
}

if ltp.vus < 1 {
return errInvalidVUs
}

if ltp.txsPerUser < 1 {
return errInvalidTxsPerUser
}

return nil
}
2 changes: 2 additions & 0 deletions command/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/0xPolygon/polygon-edge/command/bridge"
"github.com/0xPolygon/polygon-edge/command/genesis"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/command/loadtest"
"github.com/0xPolygon/polygon-edge/command/mint"
"github.com/0xPolygon/polygon-edge/command/monitor"
"github.com/0xPolygon/polygon-edge/command/peers"
Expand Down Expand Up @@ -57,6 +58,7 @@ func (rc *RootCommand) registerSubCommands() {
regenesis.GetCommand(),
mint.GetCommand(),
validator.GetCommand(),
loadtest.GetCommand(),
)
}

Expand Down
4 changes: 4 additions & 0 deletions consensus/polybft/checkpoint_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@ func (d *dummyTxRelayer) Client() *jsonrpc.EthClient {
return nil
}

func (d *dummyTxRelayer) GetTxnHashes() []types.Hash {
return nil
}

func getBlockNumberCheckpointSubmitInput(t *testing.T, input []byte) uint64 {
t.Helper()

Expand Down
14 changes: 14 additions & 0 deletions consensus/polybft/contractsapi/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ var (
TestRewardToken *contracts.Artifact
Wrapper *contracts.Artifact
NumberPersister *contracts.Artifact
ZexCoinERC20 *contracts.Artifact
ZexNFT *contracts.Artifact

contractArtifacts map[string]*contracts.Artifact
)
Expand Down Expand Up @@ -330,6 +332,16 @@ func init() {
log.Fatal(err)
}

ZexCoinERC20, err = contracts.DecodeArtifact(readTestContractContent("ZexCoinERC20.json"))
if err != nil {
log.Fatal(err)
}

ZexNFT, err = contracts.DecodeArtifact(readTestContractContent("ZexNFT.json"))
if err != nil {
log.Fatal(err)
}

contractArtifacts = map[string]*contracts.Artifact{
"CheckpointManager": CheckpointManager,
"ExitHelper": ExitHelper,
Expand Down Expand Up @@ -381,6 +393,8 @@ func init() {
"RootERC20": RootERC20,
"TestSimple": TestSimple,
"TestRewardToken": TestRewardToken,
"ZexCoinERC20": ZexCoinERC20,
"ZexNFT": ZexNFT,
}
}

Expand Down
Loading
Loading