Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ build/
tests/systemtests/binaries
tests/systemtests/testnet
.testnets

# Environments
*.env
.envrc
.venv
Empty file.
34 changes: 34 additions & 0 deletions tests/integration_tests/configs/chains.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
evmd: {
'account-prefix': 'cosmos',
evm_denom: 'atest',
cmd: 'evmd',
evm_chain_id: 262144,
bank: {
denom_metadata: [{
description: 'Native 18-decimal denom metadata for Cosmos EVM chain',
denom_units: [
{
denom: 'atest',
exponent: 0,
},
{
denom: 'test',
exponent: 18,
},
],
base: 'atest',
display: 'test',
name: 'Cosmos EVM',
symbol: 'ATOM',
}],
},
evm: {},
feemarket: {
params: {
base_fee: '1000000000',
min_gas_price: '0',
},
},
},
}
185 changes: 185 additions & 0 deletions tests/integration_tests/configs/default.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
local chain = (import 'chains.jsonnet')[std.extVar('CHAIN_CONFIG')];

{
dotenv: '../../scripts/.env',
'evm-canary-net-1': {
cmd: chain.cmd,
'start-flags': '--trace',
config: {
mempool: {
version: 'v1',
},
},
'app-config': {
evm: {
'evm-chain-id': chain.evm_chain_id,
},
grpc: {
'skip-check-header': true,
},
'minimum-gas-prices': '0' + chain.evm_denom,
'index-events': ['ethereum_tx.ethereumTxHash'],
'iavl-lazy-loading': true,
'json-rpc': {
enable: true,
address: '127.0.0.1:{EVMRPC_PORT}',
'ws-address': '127.0.0.1:{EVMRPC_PORT_WS}',
api: 'eth,net,web3,debug,txpool',
'feehistory-cap': 100,
'block-range-cap': 10000,
'logs-cap': 10000,
'gas-cap': 30000000,
'allow-unprotected-txs': true,
},
mempool: {
'max-txs': 5000,
},
},
validators: [{
'coin-type': 60,
coins: '100000000000000000000' + chain.evm_denom,
staked: '10000000000000000000' + chain.evm_denom,
gas_prices: '0.01' + chain.evm_denom,
mnemonic: '${VALIDATOR1_MNEMONIC}',
}, {
'coin-type': 60,
coins: '100000000000000000000' + chain.evm_denom,
staked: '10000000000000000000' + chain.evm_denom,
gas_prices: '0.01' + chain.evm_denom,
mnemonic: '${VALIDATOR2_MNEMONIC}',
config: {
db_backend: 'pebbledb',
},
'app-config': {
'app-db-backend': 'pebbledb',
},
}, {
'coin-type': 60,
coins: '100000000000000000000' + chain.evm_denom,
staked: '10000000000000000000' + chain.evm_denom,
gas_prices: '0.01' + chain.evm_denom,
mnemonic: '${VALIDATOR3_MNEMONIC}',
config: {
db_backend: 'goleveldb',
},
'app-config': {
'app-db-backend': 'goleveldb',
},
}],
accounts: [{
'coin-type': 60,
name: 'community',
coins: '100000000000000000000' + chain.evm_denom + ',1000000000000atoken',
mnemonic: '${COMMUNITY_MNEMONIC}',
}, {
'coin-type': 60,
name: 'signer1',
coins: '100000000000000000000' + chain.evm_denom,
mnemonic: '${SIGNER1_MNEMONIC}',
}, {
'coin-type': 60,
name: 'signer2',
coins: '100000000000000000000' + chain.evm_denom,
mnemonic: '${SIGNER2_MNEMONIC}',
}, {
'coin-type': 60,
name: 'reserve',
coins: '100000000000000000000' + chain.evm_denom,
mnemonic: '${RESERVE_MNEMONIC}',
vesting: '60s',
}],
genesis: {
consensus: {
params: {
block: {
max_bytes: '1048576',
max_gas: '81500000',
},
abci: {
vote_extensions_enable_height: '1',
},
},
},
app_state: {
evm: chain.evm {
params+: {
evm_denom: chain.evm_denom,
active_static_precompiles: [
'0x0000000000000000000000000000000000000800',
'0x0000000000000000000000000000000000000807',
],
},
},
erc20: {
native_precompiles: [
'0x4200000000000000000000000000000000000006',
],
token_pairs: [{
erc20_address: '0x4200000000000000000000000000000000000006',
denom: chain.evm_denom,
enabled: true,
contract_owner: 1,
}],
},
feemarket: chain.feemarket {
params+: {
min_gas_multiplier: '0',
},
},
gov: {
params: {
expedited_voting_period: '1s',
voting_period: '10s',
max_deposit_period: '10s',
min_deposit: [
{
denom: chain.evm_denom,
amount: '1',
},
],
expedited_min_deposit: [
{
denom: chain.evm_denom,
amount: '2',
},
],
},
},
crisis: {
constant_fee: {
denom: chain.evm_denom,
},
},
mint: {
params: {
mint_denom: chain.evm_denom,
},
},
staking: {
params: {
bond_denom: chain.evm_denom,
unbonding_time: '10s',
},
},
bank: chain.bank {
denom_metadata+: [{
denom_units+: [
{
denom: 'atoken',
exponent: 0,
},
{
denom: 'token',
exponent: 18,
},
],
base: 'atoken',
display: 'token',
name: 'Test Coin',
symbol: 'ATOKEN',
}],
},
},
},
},
}
16 changes: 16 additions & 0 deletions tests/integration_tests/configs/enable-indexer.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
local config = import 'default.jsonnet';

config {
'evm-canary-net-1'+: {
config+: {
tx_index+: {
indexer: 'null',
},
},
'app-config'+: {
'json-rpc'+: {
'enable-indexer': true,
},
},
},
}
86 changes: 86 additions & 0 deletions tests/integration_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import pytest

from .network import setup_evm


def pytest_addoption(parser):
parser.addoption(
"--chain-config",
default="evmd",
action="store",
metavar="CHAIN_CONFIG",
required=False,
help="Specify chain config to test",
)


def pytest_configure(config):
config.addinivalue_line("markers", "unmarked: fallback mark for unmarked tests")
config.addinivalue_line("markers", "slow: marks tests as slow")
config.addinivalue_line("markers", "asyncio: marks tests as asyncio")
config.addinivalue_line("markers", "connect: marks connect related tests")
config.addinivalue_line("markers", "skipped: marks skipped not supported tests")


def pytest_collection_modifyitems(items, config):
keywordexpr = config.option.keyword
markexpr = config.option.markexpr
skip_connect = pytest.mark.skip(reason="Skipping connect tests by default")
skip_rollback = pytest.mark.skip(
reason="Skipping tests not supported for inveniemd"
)
chain_config = config.getoption("chain_config")

for item in items:
# add "unmarked" marker to tests that have no markers
if not any(item.iter_markers()):
item.add_marker("unmarked")

# skip connect-marked tests unless explicitly requested
if "connect" in item.keywords:
if not (
(keywordexpr and "connect" in keywordexpr)
or (markexpr and "connect" in markexpr)
):
item.add_marker(skip_connect)

if "skipped" in item.keywords:
if chain_config != "evmd" and not (
(keywordexpr and "skipped" in keywordexpr)
or (markexpr and "skipped" in markexpr)
):
item.add_marker(skip_rollback)


@pytest.fixture(scope="session")
def suspend_capture(pytestconfig):
"""
used to pause in testing

Example:
```
def test_simple(suspend_capture):
with suspend_capture:
# read user input
print(input())
```
"""

class SuspendGuard:
def __init__(self):
self.capmanager = pytestconfig.pluginmanager.getplugin("capturemanager")

def __enter__(self):
self.capmanager.suspend_global_capture(in_=True)

def __exit__(self, _1, _2, _3):
self.capmanager.resume_global_capture()

yield SuspendGuard()


@pytest.fixture(scope="session", params=[True])
def evm(request, tmp_path_factory):
chain = request.config.getoption("chain_config")
path = tmp_path_factory.mktemp("evm")
yield from setup_evm(path, 26650, chain)
Loading
Loading