From 07e2bffec8eb29e0e8a28569a2d87916c64ed5cd Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 19 Jan 2024 11:44:09 +0100 Subject: [PATCH] Only run fixtures when used --- tests/conftest.py | 20 +++--- tests/fixtures/accounts.py | 20 ++++-- tests/fixtures/mocks.py | 2 +- tests/fixtures/pools.py | 9 ++- tests/fixtures/tokens.py | 27 +++++-- .../pools/exchange/test_exchange_received.py | 2 +- tests/pools/exchange/test_exchange_reverts.py | 5 +- tests/pools/oracle/test_oracle.py | 71 +++++++++---------- 8 files changed, 89 insertions(+), 67 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 26d71998..dfc47a6d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -40,11 +40,11 @@ def pytest_generate_tests(metafunc): if "metapool_token_type" in metafunc.fixturenames: # for meta pool only 1st coin is selected - token_type_items = sorted(TOKEN_TYPES.items()) + token_type_items = get_tokens_for_metafunc(metafunc) metafunc.parametrize( "metapool_token_type", - [v for k, v in token_type_items], - ids=[f"(MetaTokenType={k})" for k, v in token_type_items], + [number for name, number in token_type_items], + ids=[f"(MetaTokenType={name})" for name, number in token_type_items], ) if "initial_decimals" in metafunc.fixturenames: @@ -57,11 +57,7 @@ def get_pool_token_pairs(metafunc): if metafunc.definition.get_closest_marker(f"only_{name}_tokens"): return [((name, number), (name, number))] - items = [ - (name, number) - for name, number in TOKEN_TYPES.items() - if not metafunc.definition.get_closest_marker(f"skip_{name}_tokens") - ] + items = get_tokens_for_metafunc(metafunc) # make all combinations possible all_combinations = list(combinations_with_replacement(items, 2)) # make sure we get the same result in each worker @@ -70,6 +66,14 @@ def get_pool_token_pairs(metafunc): return sorted(random.sample(all_combinations, k=2)) +def get_tokens_for_metafunc(metafunc): + return [ + (name, number) + for name, number in TOKEN_TYPES.items() + if not metafunc.definition.get_closest_marker(f"skip_{name}_tokens") + ] + + @pytest.fixture(scope="session") def pool_size(): return 2 diff --git a/tests/fixtures/accounts.py b/tests/fixtures/accounts.py index e9f679e0..f519d9e4 100644 --- a/tests/fixtures/accounts.py +++ b/tests/fixtures/accounts.py @@ -6,6 +6,7 @@ from tests.utils.tokens import mint_for_testing +from ..constants import POOL_TYPES from .constants import INITIAL_AMOUNT @@ -66,9 +67,9 @@ def accounts(bob, charlie, dave, erin, frank): # <--------------------- Functions ---------------------> def mint_account(account, pool_tokens, initial_balance, initial_amounts): - mint_for_testing(account, initial_balance, None, True) + mint_for_testing(account, initial_balance, token_contract=None, mint_eth=True) for pool_token, amount in zip(pool_tokens, initial_amounts): - mint_for_testing(account, amount, pool_token, False) + mint_for_testing(account, amount, pool_token, mint_eth=False) def approve_account(account, pool_tokens, swap): @@ -196,7 +197,9 @@ def approve_meta_bob(bob, underlying_tokens, swap): @pytest.fixture() -def basic_setup(alice, bob, mint_alice, deposit_amounts, basic_swap, initial_balance, initial_amounts, pool_tokens): +def basic_setup( + alice, approve_alice, bob, mint_alice, deposit_amounts, basic_swap, initial_balance, initial_amounts, pool_tokens +): mint_for_testing(bob, 1 * 10**18, None, True) with boa.env.prank(alice): @@ -250,7 +253,10 @@ def meta_setup( @pytest.fixture() -def initial_setup(meta_setup, basic_setup, pool_type): - if pool_type == 0: - return basic_setup - return meta_setup +def initial_setup(pool_type, request): + """ + Set up the initial state for a pool test. + Run either basic_setup or meta_setup depending on the pool_type. + """ + fixture_name = {POOL_TYPES["basic"]: "basic_setup", POOL_TYPES["meta"]: "meta_setup"}[pool_type] + return request.getfixturevalue(fixture_name) diff --git a/tests/fixtures/mocks.py b/tests/fixtures/mocks.py index 723c7765..148b1b9a 100644 --- a/tests/fixtures/mocks.py +++ b/tests/fixtures/mocks.py @@ -2,7 +2,7 @@ import pytest -@pytest.fixture(scope="module") +@pytest.fixture() def callback_contract(bob, swap, pool_tokens, underlying_tokens, callback_swap_deployer): with boa.env.prank(bob): callback = callback_swap_deployer.deploy(swap.address, bob) diff --git a/tests/fixtures/pools.py b/tests/fixtures/pools.py index 3dce40c2..52ee6f9d 100644 --- a/tests/fixtures/pools.py +++ b/tests/fixtures/pools.py @@ -2,12 +2,16 @@ import pytest from eth_utils import function_signature_to_4byte_selector +from tests.constants import POOL_TYPES + ORACLE_METHOD_ID = function_signature_to_4byte_selector("exchangeRate()") OFFPEG_FEE_MULTIPLIER = 20000000000 @pytest.fixture() def basic_swap(deployer, factory, pool_size, pool_tokens, zero_address, amm_deployer, set_pool_implementations): + # factory, set_metapool_implementations, zero_address, metapool_token, base_pool, meta_deployer, add_base_pool + A = 2000 fee = 1000000 method_ids = [b""] * pool_size @@ -93,8 +97,9 @@ def meta_swap( @pytest.fixture() -def swap(basic_swap, meta_swap, pool_type): - return {0: basic_swap, 1: meta_swap}[pool_type] +def swap(request, pool_type): + fixture_name = {POOL_TYPES["basic"]: "basic_swap", POOL_TYPES["meta"]: "meta_swap"}[pool_type] + return request.getfixturevalue(fixture_name) # <--------------------- Metapool configuration ---------------------> diff --git a/tests/fixtures/tokens.py b/tests/fixtures/tokens.py index d6cc8f1e..323eaffb 100644 --- a/tests/fixtures/tokens.py +++ b/tests/fixtures/tokens.py @@ -1,6 +1,8 @@ import boa import pytest +from tests.constants import TOKEN_TYPES + @pytest.fixture() def plain_tokens(erc20_deployer, deployer, decimals): @@ -18,7 +20,7 @@ def oracle_tokens(erc20oracle_deployer, deployer, decimals): @pytest.fixture() -def rebase_tokens(erc20_rebasing_deployer, deployer, decimals): +def rebasing_tokens(erc20_rebasing_deployer, deployer, decimals): with boa.env.prank(deployer): return [ erc20_rebasing_deployer.deploy(f"OR_TKN{i}", f"OR_TKN{i}", decimals[i], True) @@ -27,15 +29,28 @@ def rebase_tokens(erc20_rebasing_deployer, deployer, decimals): @pytest.fixture() -def pool_tokens(pool_token_types, plain_tokens, oracle_tokens, rebase_tokens): - tokens = {0: plain_tokens, 1: oracle_tokens, 2: rebase_tokens} - return [tokens[t][i] for i, t in enumerate(pool_token_types)] +def pool_tokens(pool_token_types, request): + fixtures = { + TOKEN_TYPES["plain"]: "plain_tokens", + TOKEN_TYPES["oracle"]: "oracle_tokens", + TOKEN_TYPES["rebasing"]: "rebasing_tokens", + } + type1, type2 = pool_token_types + first, _ = request.getfixturevalue(fixtures[type1]) + _, second = request.getfixturevalue(fixtures[type2]) + return first, second # <--------------------- Metapool configuration ---------------------> @pytest.fixture() -def metapool_token(metapool_token_type, plain_tokens, oracle_tokens, rebase_tokens): - return {0: plain_tokens, 1: oracle_tokens, 2: rebase_tokens}[metapool_token_type][0] +def metapool_token(metapool_token_type, request): + fixture = { + TOKEN_TYPES["plain"]: "plain_tokens", + TOKEN_TYPES["oracle"]: "oracle_tokens", + TOKEN_TYPES["rebasing"]: "rebasing_tokens", + } + metapool_token, _ = request.getfixturevalue(fixture[metapool_token_type]) + return metapool_token @pytest.fixture() diff --git a/tests/pools/exchange/test_exchange_received.py b/tests/pools/exchange/test_exchange_received.py index fa642c9a..1d768b9c 100644 --- a/tests/pools/exchange/test_exchange_received.py +++ b/tests/pools/exchange/test_exchange_received.py @@ -98,8 +98,8 @@ def _transfer_and_swap(pool, sending: int, receiving: int, underlying: bool): return _transfer_and_swap -@pytest.mark.parametrize("sending,receiving", [(0, 1), (1, 0)]) @pytest.mark.skip_rebasing_tokens +@pytest.mark.parametrize("sending,receiving", [(0, 1), (1, 0)]) def test_exchange_received_nonrebasing(bob, swap, pool_tokens, sending, receiving, transfer_and_swap): swap_data = transfer_and_swap(swap, sending, receiving, False) diff --git a/tests/pools/exchange/test_exchange_reverts.py b/tests/pools/exchange/test_exchange_reverts.py index 86c7f739..a39bf515 100644 --- a/tests/pools/exchange/test_exchange_reverts.py +++ b/tests/pools/exchange/test_exchange_reverts.py @@ -12,11 +12,8 @@ def test_insufficient_balance(charlie, pool_tokens, underlying_tokens, swap, sen assert token.balanceOf(charlie) == 0 # Charlie doesn't have any tokens, all balances are 0 - try: + with boa.reverts(): swap.exchange(sending, receiving, amount + 1, 0, sender=charlie) - assert False - except: # noqa: E722 - assert True @pytest.mark.parametrize("sending,receiving", [(0, 1), (1, 0)]) diff --git a/tests/pools/oracle/test_oracle.py b/tests/pools/oracle/test_oracle.py index 09163210..cca93ea9 100644 --- a/tests/pools/oracle/test_oracle.py +++ b/tests/pools/oracle/test_oracle.py @@ -1,6 +1,7 @@ import boa import pytest +from tests.constants import POOL_TYPES from tests.fixtures.accounts import add_base_pool_liquidity, mint_account from tests.fixtures.constants import INITIAL_AMOUNT from tests.utils.tokens import mint_for_testing @@ -9,10 +10,13 @@ @pytest.fixture() -def initial_setup_alice(pool_type, basic_setup_alice, meta_setup_alice): - if pool_type == 0: - return basic_setup_alice - return meta_setup_alice +def initial_setup_alice(pool_type, request): + """ + Set up the initial state for Alice. + Run either the basic or meta fixture depending on the pool type. + """ + fixture_name = {POOL_TYPES["basic"]: "basic_setup_alice", POOL_TYPES["meta"]: "meta_setup_alice"}[pool_type] + return request.getfixturevalue(fixture_name) @pytest.fixture() @@ -76,44 +80,35 @@ def test_oracles(alice, swap, pool_size): assert swap._immutables.rate_oracles.get() != [0] * pool_size -def test_get_dy( - alice, - initial_setup_alice, - swap, - pool_type, - pool_token_types, - metapool_token_type, - decimals, - meta_decimals, - oracle_tokens, - metapool_token, +def test_get_dy_basic( + alice, initial_setup_alice, basic_swap, pool_token_types, decimals, meta_decimals, oracle_tokens, metapool_token ): - amounts = [] + amounts = [ + DEPOSIT_AMOUNT * 10 ** decimals[i] * 10**18 // oracle_tokens[i].exchangeRate() + if t == 1 + else DEPOSIT_AMOUNT * 10 ** decimals[i] + for i, t in enumerate(pool_token_types) + ] - if pool_type == 0: - for i, t in enumerate(pool_token_types): - if t != 1: - amounts.append(DEPOSIT_AMOUNT * 10 ** decimals[i]) - else: - amounts.append(DEPOSIT_AMOUNT * 10 ** decimals[i] * 10**18 // oracle_tokens[i].exchangeRate()) - else: - if metapool_token_type == 1: - amounts = [ - DEPOSIT_AMOUNT * 10**meta_decimals * 10**18 // metapool_token.exchangeRate(), - DEPOSIT_AMOUNT * 10**18, - ] - else: - amounts = [DEPOSIT_AMOUNT * 10**meta_decimals, DEPOSIT_AMOUNT * 10**18] + basic_swap.add_liquidity(amounts, 0, sender=alice) - swap.add_liquidity(amounts, 0, sender=alice) + rate_1 = 10**18 if pool_token_types[0] != 1 else oracle_tokens[0].exchangeRate() + rate_2 = 10**18 if pool_token_types[1] != 1 else oracle_tokens[1].exchangeRate() - if pool_type == 0: - rate_1 = 10**18 if pool_token_types[0] != 1 else oracle_tokens[0].exchangeRate() - rate_2 = 10**18 if pool_token_types[1] != 1 else oracle_tokens[1].exchangeRate() + assert basic_swap.get_dy(0, 1, rate_2) == pytest.approx(rate_1, rel=1e-3) - assert swap.get_dy(0, 1, rate_2) == pytest.approx(rate_1, rel=1e-3) - else: - rate_1 = 1 if metapool_token_type != 1 else metapool_token.exchangeRate() +def test_get_dy_meta( + alice, initial_setup_alice, meta_swap, metapool_token_type, decimals, meta_decimals, oracle_tokens, metapool_token +): + amounts = ( + [DEPOSIT_AMOUNT * 10**meta_decimals * 10**18 // metapool_token.exchangeRate(), DEPOSIT_AMOUNT * 10**18] + if metapool_token_type == 1 + else [DEPOSIT_AMOUNT * 10**meta_decimals, DEPOSIT_AMOUNT * 10**18] + ) + + meta_swap.add_liquidity(amounts, 0, sender=alice) + + rate_1 = 1 if metapool_token_type != 1 else metapool_token.exchangeRate() - assert swap.get_dy(0, 1, 10**18) == pytest.approx(rate_1, rel=1e-3) + assert meta_swap.get_dy(0, 1, 10**18) == pytest.approx(rate_1, rel=1e-3)