Skip to content

Commit 110807a

Browse files
docs: load (#4132)
1 parent 24a051a commit 110807a

File tree

2 files changed

+227
-0
lines changed

2 files changed

+227
-0
lines changed

tests/load/README.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Load Testing
2+
3+
The `load` package is a framework for performing load testing
4+
against an instance of the C-Chain. It allows for simulation of various
5+
transaction scenarios to test network performance, transaction throughput, and system
6+
resilience under different workloads.
7+
8+
This package also comes with `main`, a subpackage executable which runs a load test against
9+
an instance of the C-Chain. For information on how to run the executable, refer to
10+
the `main` [README.md](./main/README.md).
11+
12+
## Prerequisites
13+
14+
Using the `load` package has so far been coupled with `tmpnet`, a framework that
15+
enables orchestration of temporary AvalancheGo networks. For more details as to
16+
its capabilities and configuration, refer to the `tmpnet` [README.md](../fixture/tmpnet/README.md).
17+
18+
## Components
19+
20+
### Worker
21+
22+
Workers represent accounts which will be used for load testing. Each worker consists of a private key, nonce, and a network client - these values are used to create a wallet for load testing.
23+
24+
### Wallet
25+
26+
A wallet manages account state and transaction lifecycle for a single account.
27+
28+
The main function of wallets is to send transactions; wallets take signed transactions
29+
and send them to the network while monitoring block headers to detect transaction inclusion. A wallet
30+
considers a transaction successful if its execution succeeded, and returns an error otherwise.
31+
Upon confirming a transaction was successful, a wallet increments its nonce by one, ensuring its account
32+
state matches that of the network.
33+
34+
Wallets are not thread-safe and each account should have at most one wallet
35+
instance associated with it. Having multiple wallets associated with a single
36+
account, or using an account outside of a wallet, can cause synchronization
37+
issues. This risks a wallet's state becoming inconsistent with the network,
38+
potentially leading to failed transactions.
39+
40+
Wallets are not thread-safe and each account should have at most one wallet instance associated with it.
41+
42+
### Generator
43+
44+
The generator executes multiple tests concurrently against the network. The key features of the
45+
generator are as follows:
46+
47+
- **Parallel Execution**: Runs a goroutine per wallet for concurrent test execution.
48+
- **Timeout Management**: Supports both overall load test timeout and a timeout per-test.
49+
- **Error Recovery**: Automatically recovers from test failures to ensure continuous load generation.
50+
- **Metrics**: Creates metrics during wallet initialization and tracks performance throughout execution.
51+
52+
The generator starts a goroutine for each wallet to execute tests asynchronously, maximizing throughput while maintaining isolation between accounts.
53+
54+
### Tests
55+
56+
The `load` package performs load testing by continuously running a series of tests. This approach provides the following benefits:
57+
58+
- **Correctness**: Each test validates transaction execution and state changes, ensuring the network behaves as expected under load
59+
- **Reproducibility**: Standardized test scenarios with consistent parameters enable repeatable performance measurements and regression detection
60+
61+
Each test must satisfy the following interface for compatibility with the load generator:
62+
63+
```go
64+
type Test interface {
65+
// Run should create a signed transaction and broadcast it to the network via wallet.
66+
Run(tc tests.TestContext, ctx context.Context, wallet *Wallet)
67+
}
68+
```
69+
70+
#### Available Test Types
71+
72+
The `load` package provides a comprehensive suite of test types designed to stress different aspects of EVM execution. Each test targets specific performance characteristics and resource usage patterns.
73+
74+
| Test Type | Description |
75+
| ----------------- | --------------------------------------------------------------- |
76+
| Transfer | Performs self-transfer of 0 AVAX |
77+
| Read | Performs multiple storage reads from contract state |
78+
| Write | Executes equential storage writes to new contract storage slots |
79+
| StateModification | Updates existing storage values or creates new ones |
80+
| Hashing | Executes Keccak256 hash operations in a loop |
81+
| PureCompute | Performs CPU-intensive mathematical computations |
82+
| Memory | Allocates and manipulates dynamic arrays |
83+
| CallDepth | Performs recursive function calls to test stack limits |
84+
| ContractCreation | Deploys new contracts during execution |
85+
| ExternalCall | Makes calls to external contract functions |
86+
| LargeEvent | Emits events with large data payloads |
87+
| TrieStress | Performs insert operations on TrieDB |
88+
89+
Additionally, there is a `RandomTest` which executes one of the aforementioned tests, selected uniformly at random.
90+
This test is particular useful for mimicking the diverse transactions patterns seen on blockchains like the C-Chain.
91+
92+
### Metrics
93+
94+
The package exposes Prometheus metrics for comprehensive load test monitoring:
95+
96+
- **`txs_issued`** (Counter): Total number of transactions submitted to the network
97+
- **`tx_issuance_latency`** (Histogram): Time from transaction creation to network submission
98+
- **`tx_confirmation_latency`** (Histogram): Time from network submission to block confirmation
99+
- **`tx_total_latency`** (Histogram): End-to-end time from creation to confirmation
100+
101+
These metrics are registered with the registry passed into the load generator during initialization and are updated via the wallets during test execution.
102+

tests/load/main/README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# EVM Load Test
2+
3+
This executable utilizes the `load` package to perform a load test against an instance of the C-Chain.
4+
5+
## Prerequisites
6+
7+
Using this executable requires `nix`: to install `nix`, please refer to the AvalancheGo [flake.nix](../../../flake.nix) file for installation instructions.
8+
Furthermore, utilization of any monitoring features requires credentials to the
9+
Avalanche monitoring stack.
10+
11+
Reading the `load` package [README.md](../README.md) is highly recommended as well,
12+
especially for those considering modifying this executable for their own load tests.
13+
14+
## Quick Start
15+
16+
To run an EVM load test, execute the following commands:
17+
18+
```bash
19+
# Start nix development environment
20+
nix develop
21+
22+
# Start load test with monitoring
23+
task test-load -- --start-metrics-collector --start-logs-collector
24+
```
25+
26+
This command will create a temporary Avalanche network and perform any test setup prior
27+
to starting the load test.
28+
29+
### Monitoring
30+
31+
The test will start a new Avalanche network along with deploying a set of
32+
wallets which will send transactions to the network for the lifetime of the test.
33+
To enable viewing the state of the test network, `tmpnet` will log a Grafana URL:
34+
35+
```
36+
[07-25|13:47:36.137] INFO tmpnet/network.go:410 metrics and logs available via grafana (collectors must be running) {"url": "https://grafana-poc.avax-dev.network/d/kBQpRdWnk/avalanche-main-dashboard?&var-filter=network_uuid%7C%3D%7Ce1b9dd69-5204-4c24-8b98-d3aea14c0eeb&var-filter=is_ephemeral_node%7C%3D%7Cfalse&from=1753465644564&to=now"}
37+
```
38+
39+
Clicking on this link will open the main AvalancheGo dashboard in Grafana
40+
filtered to display only results from the test.
41+
42+
## Architecture
43+
44+
```mermaid
45+
flowchart BT
46+
subgraph MetricsServer[Metrics Server]
47+
Metrics
48+
end
49+
50+
subgraph Generator
51+
subgraph TestA[Test A]
52+
WalletA[Wallet A]
53+
end
54+
subgraph TestB[Test B]
55+
WalletB[Wallet B]
56+
end
57+
subgraph TestC[Test C]
58+
WalletC[Wallet C]
59+
end
60+
end
61+
62+
subgraph Network
63+
NodeA
64+
NodeB
65+
NodeC
66+
end
67+
68+
Generator --> Metrics
69+
70+
WalletA --> NodeA
71+
WalletB --> NodeB
72+
WalletC --> NodeC
73+
```
74+
75+
The load test architecture consists of two main components that work together to simulate realistic blockchain usage and a metrics server which exposes client-side metrics.
76+
77+
### Network
78+
79+
The network is created via `tmpnet`, which provisions a temporary cluster of validator nodes. The number of nodes is configurable through the `--node-count` flag (default: 5).
80+
In addition to network creation, the executable directs `tmpnet` to create a prefunded account for each worker.
81+
82+
#### Kubernetes Support
83+
84+
By default, the nodes of a network created by a load test are local processes. However, it's possible for network nodes to run within a Kubernetes cluster as pods. For example, to run a load test with nodes in a [Kind](https://kind.sigs.k8s.io/) cluster, execute the following:
85+
86+
```bash
87+
# Start nix development environment
88+
nix develop
89+
90+
# Start load test against Kind cluster
91+
task test-load-kube-kind
92+
```
93+
94+
`nix` handles the installation of any Kubernetes/Kind dependencies, making it trivial to run load tests with a Kind cluster.
95+
96+
### Load Generator
97+
98+
The load generator is setup as follows:
99+
100+
1. Deploy an instance of the `EVMLoadSimulator` contract
101+
2. Create an instance of `RandomTest` which uses the deployed contract
102+
3. Create an instance of `LoadGenerator` with a worker per node
103+
4. Start the generator
104+
105+
### Metrics Server
106+
107+
For client-side metrics to be collected by `tmpnet` and uploaded to the Avalanche
108+
monitoring stack, this executable also starts a metric server which exports the registry metrics
109+
updated by the generator/wallets. The server is configured to be targeted by
110+
`tmpnet`'s metrics collector via a service discovery config.
111+
112+
## Configuration
113+
114+
### Load Test Flags
115+
116+
- `--load-timeout`: Maximum duration to run the load test (default: unlimited)
117+
118+
### Network Configuration (`tmpnet` Flags)
119+
120+
The following common flags control the underlying Avalanche network setup:
121+
122+
- `--node-count`: Number of validator nodes in the test network (default: 5)
123+
- `--start-metrics-collector`: Starts a metrics collector for node and test metrics. If already running, this is a no-op.
124+
- `--start-logs-collector`: Starts a logs collector for node output. If already running, this is a no-op.
125+

0 commit comments

Comments
 (0)