From fc543c49dc1ea6b5c2de78ecb5b0c88fdae004db Mon Sep 17 00:00:00 2001 From: Kieran Prasch Date: Thu, 24 Aug 2023 14:26:29 +0200 Subject: [PATCH] dehydrate multichain test mocks and utilities for fixture resuse in multiple suites. --- .../conditions/test_multichain_evaluation.py | 63 ++----------------- tests/acceptance/conftest.py | 39 ++++++++++++ tests/integration/conftest.py | 37 ++++++----- tests/utils/ursula.py | 33 +++++++++- 4 files changed, 97 insertions(+), 75 deletions(-) diff --git a/tests/acceptance/conditions/test_multichain_evaluation.py b/tests/acceptance/conditions/test_multichain_evaluation.py index d8c82b6be..bdc1da835 100644 --- a/tests/acceptance/conditions/test_multichain_evaluation.py +++ b/tests/acceptance/conditions/test_multichain_evaluation.py @@ -1,12 +1,10 @@ from collections import defaultdict import pytest -from web3 import HTTPProvider -from nucypher.policy.conditions.evm import _CONDITION_CHAINS, RPCCondition +from nucypher.policy.conditions.evm import RPCCondition from nucypher.policy.conditions.lingo import ConditionLingo, ConditionType from nucypher.utilities.logging import GlobalLoggerSettings -from tests.constants import TESTERCHAIN_CHAIN_ID from tests.utils.policy import make_message_kits GlobalLoggerSettings.start_text_file_logging() @@ -45,66 +43,13 @@ def make_multichain_evm_conditions(bob, chain_ids): @pytest.fixture(scope="module") -def chain_ids(module_mocker): - ids = [ - TESTERCHAIN_CHAIN_ID, - TESTERCHAIN_CHAIN_ID + 1, - TESTERCHAIN_CHAIN_ID + 2, - 123456789, - ] - module_mocker.patch.dict( - _CONDITION_CHAINS, {cid: "fakechain/mainnet" for cid in ids} - ) - return ids - - -@pytest.fixture(scope="module", autouse=True) -def multichain_ursulas(ursulas, chain_ids): - base_uri = "tester://multichain.{}" - base_fallback_uri = "tester://multichain.fallback.{}" - provider_uris = [base_uri.format(i) for i in range(len(chain_ids))] - fallback_provider_uris = [ - base_fallback_uri.format(i) for i in range(len(chain_ids)) - ] - mocked_condition_providers = { - cid: {HTTPProvider(uri), HTTPProvider(furi)} - for cid, uri, furi in zip(chain_ids, provider_uris, fallback_provider_uris) - } - for ursula in ursulas: - ursula.condition_providers = mocked_condition_providers - return ursulas - - -@pytest.fixture(scope="module") -def conditions(bob, chain_ids): - _conditions = make_multichain_evm_conditions(bob, chain_ids) +def conditions(bob, multichain_ids): + _conditions = make_multichain_evm_conditions(bob, multichain_ids) return _conditions -@pytest.fixture(scope="module") -def monkeymodule(): - from _pytest.monkeypatch import MonkeyPatch - - mpatch = MonkeyPatch() - yield mpatch - mpatch.undo() - - -@pytest.fixture(scope="module") -def mock_rpc_condition(module_mocker, testerchain, monkeymodule): - def configure_mock(condition, provider, *args, **kwargs): - condition.provider = provider - return testerchain.w3 - - monkeymodule.setattr(RPCCondition, "_configure_w3", configure_mock) - configure_spy = module_mocker.spy(RPCCondition, "_configure_w3") - - chain_id_check_mock = module_mocker.patch.object(RPCCondition, "_check_chain_id") - return configure_spy, chain_id_check_mock - - def test_single_retrieve_with_multichain_conditions( - enacted_policy, bob, multichain_ursulas, conditions, mock_rpc_condition, mocker + enacted_policy, bob, multichain_ursulas, conditions, mock_rpc_condition ): bob.remember_node(multichain_ursulas[0]) bob.start_learning_loop() diff --git a/tests/acceptance/conftest.py b/tests/acceptance/conftest.py index 78a080e29..60dc785b2 100644 --- a/tests/acceptance/conftest.py +++ b/tests/acceptance/conftest.py @@ -11,6 +11,7 @@ from nucypher.blockchain.eth.networks import NetworksInventory from nucypher.blockchain.eth.signers.software import Web3Signer from nucypher.config.constants import TEMPORARY_DOMAIN from nucypher.crypto.powers import CryptoPower, TransactingPower +from nucypher.policy.conditions.evm import RPCCondition from nucypher.policy.payment import SubscriptionManagerPayment from nucypher.utilities.logging import Logger from tests.constants import ( @@ -24,6 +25,10 @@ from tests.constants import ( from tests.utils.ape import deploy_contracts as ape_deploy_contracts from tests.utils.ape import registry_from_ape_deployments from tests.utils.blockchain import TesterBlockchain +from tests.utils.ursula import ( + mock_permitted_multichain_connections, + setup_multichain_ursulas, +) test_logger = Logger("acceptance-test-logger") @@ -163,3 +168,37 @@ def manual_operator(testerchain): txhash = testerchain.client.w3.eth.send_transaction(tx) _receipt = testerchain.wait_for_receipt(txhash) yield address + + +@pytest.fixture(scope="module") +def monkeymodule(): + from _pytest.monkeypatch import MonkeyPatch + + mpatch = MonkeyPatch() + yield mpatch + mpatch.undo() + + +@pytest.fixture(scope="module") +def mock_rpc_condition(module_mocker, testerchain, monkeymodule): + def configure_mock(condition, provider, *args, **kwargs): + condition.provider = provider + return testerchain.w3 + + monkeymodule.setattr(RPCCondition, "_configure_w3", configure_mock) + configure_spy = module_mocker.spy(RPCCondition, "_configure_w3") + + chain_id_check_mock = module_mocker.patch.object(RPCCondition, "_check_chain_id") + return configure_spy, chain_id_check_mock + + +@pytest.fixture(scope="module") +def multichain_ids(module_mocker): + ids = mock_permitted_multichain_connections(mocker=module_mocker) + return ids + + +@pytest.fixture(scope="module") +def multichain_ursulas(ursulas, multichain_ids, mock_rpc_condition): + setup_multichain_ursulas(ursulas=ursulas, chain_ids=multichain_ids) + return ursulas diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 737730ad8..4667bd892 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,15 +1,17 @@ -import pytest -from eth_account.account import Account from pathlib import Path from typing import Iterable, Optional +import pytest +from eth_account.account import Account + from nucypher.blockchain.economics import EconomicsFactory -from nucypher.blockchain.eth.actors import Operator, Ritualist +from nucypher.blockchain.eth.actors import Operator from nucypher.blockchain.eth.agents import ( AdjudicatorAgent, ContractAgency, + CoordinatorAgent, PREApplicationAgent, - StakingProvidersReservoir, CoordinatorAgent, + StakingProvidersReservoir, ) from nucypher.blockchain.eth.interfaces import ( BlockchainInterface, @@ -31,23 +33,16 @@ from tests.constants import ( ) from tests.mock.interfaces import MockBlockchain, mock_registry_source_manager from tests.mock.io import MockStdinWrapper +from tests.utils.ursula import ( + mock_permitted_multichain_connections, + setup_multichain_ursulas, +) def pytest_addhooks(pluginmanager): pluginmanager.set_blocked('ape_test') -@pytest.fixture(scope='function', autouse=True) -def mock_contract_agency(monkeypatch, module_mocker, application_economics): - from tests.mock.agents import MockContractAgency - - monkeypatch.setattr(ContractAgency, 'get_agent', MockContractAgency.get_agent) - module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=application_economics) - mock_agency = MockContractAgency() - yield mock_agency - mock_agency.reset() - - @pytest.fixture(scope="module", autouse=True) def mock_sample_reservoir(testerchain, mock_contract_agency): def mock_reservoir( @@ -264,3 +259,15 @@ def mock_condition_blockchains(session_mocker): session_mocker.patch.object( NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID ) + + +@pytest.fixture(scope="module") +def multichain_ids(module_mocker): + ids = mock_permitted_multichain_connections(mocker=module_mocker) + return ids + + +@pytest.fixture(scope="module") +def multichain_ursulas(ursulas, multichain_ids): + setup_multichain_ursulas(ursulas=ursulas, chain_ids=multichain_ids) + return ursulas diff --git a/tests/utils/ursula.py b/tests/utils/ursula.py index bb12fda15..d21b5b089 100644 --- a/tests/utils/ursula.py +++ b/tests/utils/ursula.py @@ -4,10 +4,15 @@ from threading import Lock from typing import Iterable, List from cryptography.x509 import Certificate +from web3 import HTTPProvider from nucypher.characters.lawful import Ursula from nucypher.config.characters import UrsulaConfiguration -from tests.constants import NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK +from nucypher.policy.conditions.evm import _CONDITION_CHAINS +from tests.constants import ( + NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK, + TESTERCHAIN_CHAIN_ID, +) class __ActivePortCache: @@ -116,4 +121,30 @@ def start_pytest_ursula_services(ursula: Ursula) -> Certificate: return certificate_as_deployed +def mock_permitted_multichain_connections(mocker) -> List[int]: + ids = [ + TESTERCHAIN_CHAIN_ID, + TESTERCHAIN_CHAIN_ID + 1, + TESTERCHAIN_CHAIN_ID + 2, + 123456789, + ] + mocker.patch.dict(_CONDITION_CHAINS, {cid: "fakechain/mainnet" for cid in ids}) + return ids + + +def setup_multichain_ursulas(chain_ids: List[int], ursulas: List[Ursula]) -> None: + base_uri = "tester://multichain.{}" + base_fallback_uri = "tester://multichain.fallback.{}" + provider_uris = [base_uri.format(i) for i in range(len(chain_ids))] + fallback_provider_uris = [ + base_fallback_uri.format(i) for i in range(len(chain_ids)) + ] + mocked_condition_providers = { + cid: {HTTPProvider(uri), HTTPProvider(furi)} + for cid, uri, furi in zip(chain_ids, provider_uris, fallback_provider_uris) + } + for ursula in ursulas: + ursula.condition_providers = mocked_condition_providers + + MOCK_KNOWN_URSULAS_CACHE = dict()