Skip to content

Commit 4984383

Browse files
committed
test: add e2e for evm
1 parent c0fb92a commit 4984383

21 files changed

+6200
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ build/
3737
tests/systemtests/binaries
3838
tests/systemtests/testnet
3939
.testnets
40+
41+
# Environments
42+
*.env
43+
.envrc
44+
.venv

tests/integration_tests/__init__.py

Whitespace-only changes.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
evmd: {
3+
'account-prefix': 'cosmos',
4+
evm_denom: 'atest',
5+
cmd: 'evmd',
6+
evm_chain_id: 262144,
7+
bank: {
8+
denom_metadata: [{
9+
description: 'Native 18-decimal denom metadata for Cosmos EVM chain',
10+
denom_units: [
11+
{
12+
denom: 'atest',
13+
exponent: 0,
14+
},
15+
{
16+
denom: 'test',
17+
exponent: 18,
18+
},
19+
],
20+
base: 'atest',
21+
display: 'test',
22+
name: 'Cosmos EVM',
23+
symbol: 'ATOM',
24+
}],
25+
},
26+
evm: {},
27+
feemarket: {
28+
params: {
29+
base_fee: '1000000000',
30+
min_gas_price: '0',
31+
},
32+
},
33+
},
34+
}
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
local chain = (import 'chains.jsonnet')[std.extVar('CHAIN_CONFIG')];
2+
3+
{
4+
dotenv: '../../scripts/.env',
5+
'mantra-canary-net-1': {
6+
cmd: chain.cmd,
7+
'start-flags': '--trace',
8+
config: {
9+
mempool: {
10+
version: 'v1',
11+
},
12+
},
13+
'app-config': {
14+
evm: {
15+
'evm-chain-id': chain.evm_chain_id,
16+
},
17+
grpc: {
18+
'skip-check-header': true,
19+
},
20+
'minimum-gas-prices': '0' + chain.evm_denom,
21+
'index-events': ['ethereum_tx.ethereumTxHash'],
22+
'iavl-lazy-loading': true,
23+
'json-rpc': {
24+
enable: true,
25+
address: '127.0.0.1:{EVMRPC_PORT}',
26+
'ws-address': '127.0.0.1:{EVMRPC_PORT_WS}',
27+
api: 'eth,net,web3,debug,txpool',
28+
'feehistory-cap': 100,
29+
'block-range-cap': 10000,
30+
'logs-cap': 10000,
31+
'gas-cap': 30000000,
32+
'allow-unprotected-txs': true,
33+
},
34+
mempool: {
35+
'max-txs': 5000,
36+
},
37+
},
38+
validators: [{
39+
'coin-type': 60,
40+
coins: '100000000000000000000' + chain.evm_denom,
41+
staked: '10000000000000000000' + chain.evm_denom,
42+
gas_prices: '0.01' + chain.evm_denom,
43+
mnemonic: '${VALIDATOR1_MNEMONIC}',
44+
}, {
45+
'coin-type': 60,
46+
coins: '100000000000000000000' + chain.evm_denom,
47+
staked: '10000000000000000000' + chain.evm_denom,
48+
gas_prices: '0.01' + chain.evm_denom,
49+
mnemonic: '${VALIDATOR2_MNEMONIC}',
50+
config: {
51+
db_backend: 'pebbledb',
52+
},
53+
'app-config': {
54+
'app-db-backend': 'pebbledb',
55+
},
56+
}, {
57+
'coin-type': 60,
58+
coins: '100000000000000000000' + chain.evm_denom,
59+
staked: '10000000000000000000' + chain.evm_denom,
60+
gas_prices: '0.01' + chain.evm_denom,
61+
mnemonic: '${VALIDATOR3_MNEMONIC}',
62+
config: {
63+
db_backend: 'goleveldb',
64+
},
65+
'app-config': {
66+
'app-db-backend': 'goleveldb',
67+
},
68+
}],
69+
accounts: [{
70+
'coin-type': 60,
71+
name: 'community',
72+
coins: '100000000000000000000' + chain.evm_denom + ',1000000000000atoken',
73+
mnemonic: '${COMMUNITY_MNEMONIC}',
74+
}, {
75+
'coin-type': 60,
76+
name: 'signer1',
77+
coins: '100000000000000000000' + chain.evm_denom,
78+
mnemonic: '${SIGNER1_MNEMONIC}',
79+
}, {
80+
'coin-type': 60,
81+
name: 'signer2',
82+
coins: '100000000000000000000' + chain.evm_denom,
83+
mnemonic: '${SIGNER2_MNEMONIC}',
84+
}, {
85+
'coin-type': 60,
86+
name: 'reserve',
87+
coins: '100000000000000000000' + chain.evm_denom,
88+
mnemonic: '${RESERVE_MNEMONIC}',
89+
vesting: '60s',
90+
}],
91+
genesis: {
92+
consensus: {
93+
params: {
94+
block: {
95+
max_bytes: '1048576',
96+
max_gas: '81500000',
97+
},
98+
abci: {
99+
vote_extensions_enable_height: '1',
100+
},
101+
},
102+
},
103+
app_state: {
104+
evm: chain.evm {
105+
params+: {
106+
evm_denom: chain.evm_denom,
107+
active_static_precompiles: [
108+
'0x0000000000000000000000000000000000000800',
109+
'0x0000000000000000000000000000000000000807',
110+
],
111+
},
112+
},
113+
erc20: {
114+
native_precompiles: [
115+
'0x4200000000000000000000000000000000000006',
116+
],
117+
token_pairs: [{
118+
erc20_address: '0x4200000000000000000000000000000000000006',
119+
denom: chain.evm_denom,
120+
enabled: true,
121+
contract_owner: 1,
122+
}],
123+
},
124+
feemarket: chain.feemarket {
125+
params+: {
126+
min_gas_multiplier: '0',
127+
},
128+
},
129+
gov: {
130+
params: {
131+
expedited_voting_period: '1s',
132+
voting_period: '10s',
133+
max_deposit_period: '10s',
134+
min_deposit: [
135+
{
136+
denom: chain.evm_denom,
137+
amount: '1',
138+
},
139+
],
140+
expedited_min_deposit: [
141+
{
142+
denom: chain.evm_denom,
143+
amount: '2',
144+
},
145+
],
146+
},
147+
},
148+
crisis: {
149+
constant_fee: {
150+
denom: chain.evm_denom,
151+
},
152+
},
153+
mint: {
154+
params: {
155+
mint_denom: chain.evm_denom,
156+
},
157+
},
158+
staking: {
159+
params: {
160+
bond_denom: chain.evm_denom,
161+
unbonding_time: '10s',
162+
},
163+
},
164+
bank: chain.bank {
165+
denom_metadata+: [{
166+
denom_units+: [
167+
{
168+
denom: 'atoken',
169+
exponent: 0,
170+
},
171+
{
172+
denom: 'token',
173+
exponent: 18,
174+
},
175+
],
176+
base: 'atoken',
177+
display: 'token',
178+
name: 'Test Coin',
179+
symbol: 'ATOKEN',
180+
}],
181+
},
182+
},
183+
},
184+
},
185+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
local config = import 'default.jsonnet';
2+
3+
config {
4+
'mantra-canary-net-1'+: {
5+
config+: {
6+
tx_index+: {
7+
indexer: 'null',
8+
},
9+
},
10+
'app-config'+: {
11+
'json-rpc'+: {
12+
'enable-indexer': true,
13+
},
14+
},
15+
},
16+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import pytest
2+
3+
from .network import setup_mantra
4+
5+
6+
def pytest_addoption(parser):
7+
parser.addoption(
8+
"--chain-config",
9+
default="mantrachaind",
10+
action="store",
11+
metavar="CHAIN_CONFIG",
12+
required=False,
13+
help="Specify chain config to test",
14+
)
15+
16+
17+
def pytest_configure(config):
18+
config.addinivalue_line("markers", "unmarked: fallback mark for unmarked tests")
19+
config.addinivalue_line("markers", "slow: marks tests as slow")
20+
config.addinivalue_line("markers", "asyncio: marks tests as asyncio")
21+
config.addinivalue_line("markers", "connect: marks connect related tests")
22+
config.addinivalue_line("markers", "skipped: marks skipped not supported tests")
23+
24+
25+
def pytest_collection_modifyitems(items, config):
26+
keywordexpr = config.option.keyword
27+
markexpr = config.option.markexpr
28+
skip_connect = pytest.mark.skip(reason="Skipping connect tests by default")
29+
skip_rollback = pytest.mark.skip(
30+
reason="Skipping tests not supported for inveniemd"
31+
)
32+
chain_config = config.getoption("chain_config")
33+
34+
for item in items:
35+
# add "unmarked" marker to tests that have no markers
36+
if not any(item.iter_markers()):
37+
item.add_marker("unmarked")
38+
39+
# skip connect-marked tests unless explicitly requested
40+
if "connect" in item.keywords:
41+
if not (
42+
(keywordexpr and "connect" in keywordexpr)
43+
or (markexpr and "connect" in markexpr)
44+
):
45+
item.add_marker(skip_connect)
46+
47+
if "skipped" in item.keywords:
48+
if chain_config != "mantrachaind" and not (
49+
(keywordexpr and "skipped" in keywordexpr)
50+
or (markexpr and "skipped" in markexpr)
51+
):
52+
item.add_marker(skip_rollback)
53+
54+
55+
@pytest.fixture(scope="session")
56+
def suspend_capture(pytestconfig):
57+
"""
58+
used to pause in testing
59+
60+
Example:
61+
```
62+
def test_simple(suspend_capture):
63+
with suspend_capture:
64+
# read user input
65+
print(input())
66+
```
67+
"""
68+
69+
class SuspendGuard:
70+
def __init__(self):
71+
self.capmanager = pytestconfig.pluginmanager.getplugin("capturemanager")
72+
73+
def __enter__(self):
74+
self.capmanager.suspend_global_capture(in_=True)
75+
76+
def __exit__(self, _1, _2, _3):
77+
self.capmanager.resume_global_capture()
78+
79+
yield SuspendGuard()
80+
81+
82+
@pytest.fixture(scope="session", params=[True])
83+
def mantra(request, tmp_path_factory):
84+
chain = request.config.getoption("chain_config")
85+
path = tmp_path_factory.mktemp("mantra")
86+
yield from setup_mantra(path, 26650, chain)

0 commit comments

Comments
 (0)