diff --git a/tests/conftest.py b/tests/conftest.py index 6f4f91a02..9c420b50e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,11 +3,8 @@ from umbral.config import set_default_curve set_default_curve(ec.SECP256K1()) - -# NOTICE: Depends on fixture modules; do not delete -from .eth_fixtures import * +"""NOTICE: Depends on fixture modules; do not delete""" from .fixtures import * - import pytest diff --git a/tests/eth_fixtures.py b/tests/eth_fixtures.py deleted file mode 100644 index 4f1a14a70..000000000 --- a/tests/eth_fixtures.py +++ /dev/null @@ -1,120 +0,0 @@ -import contextlib -import os - -import pytest -from constant_sorrow import constants -from eth_tester import EthereumTester -from os.path import abspath, dirname -from web3 import EthereumTesterProvider - -from nucypher.blockchain.eth.chains import TesterBlockchain -from nucypher.blockchain.eth.deployers import PolicyManagerDeployer, NucypherTokenDeployer, MinerEscrowDeployer -from nucypher.blockchain.eth.interfaces import DeployerCircumflex -from nucypher.blockchain.eth.sol.compile import SolidityCompiler -from nucypher.blockchain.eth.utilities import OverridablePyEVMBackend, TemporaryEthereumContractRegistry -from tests.blockchain.eth import contracts -from tests.blockchain.eth.utilities import token_airdrop -from tests.utilities import make_ursulas - -constants.NUMBER_OF_TEST_ETH_ACCOUNTS(10) - - - -# -# Blockchain -# - -@pytest.fixture(scope='session') -def solidity_compiler(): - """Doing this more than once per session will result in slower test run times.""" - test_contracts_dir = os.path.join(dirname(abspath(contracts.__file__)), 'contracts') - compiler = SolidityCompiler(test_contract_dir=test_contracts_dir) - yield compiler - - -@pytest.fixture(scope='module') -def testerchain(solidity_compiler): - """ - https: // github.com / ethereum / eth - tester # available-backends - """ - - temp_registrar = TemporaryEthereumContractRegistry() - - # Configure a custom provider - overrides = {'gas_limit': 4626271} - pyevm_backend = OverridablePyEVMBackend(genesis_overrides=overrides) - - eth_tester = EthereumTester(backend=pyevm_backend, auto_mine_transactions=True) - pyevm_provider = EthereumTesterProvider(ethereum_tester=eth_tester) - - # Use the the custom provider and registrar to init an interface - circumflex = DeployerCircumflex(compiler=solidity_compiler, # freshly recompile - registry=temp_registrar, # use temporary registrar - providers=(pyevm_provider, )) # use custom test provider - - # Create the blockchain - testerchain = TesterBlockchain(interface=circumflex, test_accounts=10) - origin, *everyone = testerchain.interface.w3.eth.accounts - circumflex.deployer_address = origin # Set the deployer address from a freshly created test account - - yield testerchain - - testerchain.sever_connection() - - -@pytest.fixture(scope='module') -def three_agents(testerchain): - """ - Musketeers, if you will. - Launch the big three contracts on provided chain, - make agents for each and return them. - """ - - """Launch all Nucypher ethereum contracts""" - origin, *everybody_else = testerchain.interface.w3.eth.accounts - - token_deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) - token_deployer.arm() - token_deployer.deploy() - - token_agent = token_deployer.make_agent() - - miner_escrow_deployer = MinerEscrowDeployer(token_agent=token_agent, deployer_address=origin) - miner_escrow_deployer.arm() - miner_escrow_deployer.deploy() - - miner_agent = miner_escrow_deployer.make_agent() - - policy_manager_deployer = PolicyManagerDeployer(miner_agent=miner_agent, deployer_address=origin) - policy_manager_deployer.arm() - policy_manager_deployer.deploy() - - policy_agent = policy_manager_deployer.make_agent() - - return token_agent, miner_agent, policy_agent - - -@pytest.fixture(scope="module") -def non_ursula_miners(three_agents): - token_agent, miner_agent, policy_agent = three_agents - etherbase, alice, bob, *all_yall = token_agent.blockchain.interface.w3.eth.accounts - - ursula_addresses = all_yall[:int(constants.NUMBER_OF_URSULAS_IN_NETWORK)] - - _receipts = token_airdrop(token_agent=token_agent, origin=etherbase, - addresses=all_yall, amount=1000000 * constants.M) - - starting_point = constants.URSULA_PORT_SEED + 500 - - _ursulas = make_ursulas(ether_addresses=ursula_addresses, - ursula_starting_port=int(starting_point), - miner_agent=miner_agent, - miners=True, - bare=True) - try: - yield _ursulas - finally: - # Remove the DBs that have been sprayed hither and yon. - with contextlib.suppress(FileNotFoundError): - for port, ursula in enumerate(_ursulas, start=int(starting_point)): - os.remove("test-{}".format(port)) diff --git a/tests/fixtures.py b/tests/fixtures.py index adfce3b29..32dede483 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -1,32 +1,61 @@ import contextlib -import datetime import os import tempfile +from os.path import abspath, dirname +import datetime import maya import pytest -from sqlalchemy.engine import create_engine - from constant_sorrow import constants -from eth_utils import to_canonical_address, to_checksum_address +from eth_tester import EthereumTester +from eth_utils import to_checksum_address +from sqlalchemy.engine import create_engine +from web3 import EthereumTesterProvider + +from nucypher.blockchain.eth.chains import TesterBlockchain +from nucypher.blockchain.eth.deployers import PolicyManagerDeployer, NucypherTokenDeployer, MinerEscrowDeployer +from nucypher.blockchain.eth.interfaces import DeployerCircumflex +from nucypher.blockchain.eth.sol.compile import SolidityCompiler +from nucypher.blockchain.eth.utilities import OverridablePyEVMBackend, TemporaryEthereumContractRegistry from nucypher.characters import Alice, Bob from nucypher.data_sources import DataSource from nucypher.keystore import keystore from nucypher.keystore.db import Base from nucypher.keystore.keypairs import SigningKeypair +from tests.blockchain.eth import contracts from tests.blockchain.eth.utilities import token_airdrop -from tests.utilities import make_ursulas, MockRestMiddleware +from tests.utilities import MockRestMiddleware +from tests.utilities import make_ursulas + +# +# Setup +# + +constants.NUMBER_OF_TEST_ETH_ACCOUNTS(10) + + +@pytest.fixture(scope="function") +def tempfile_path(): + """ + User is responsible for closing the file given at the path. + """ + _, path = tempfile.mkstemp() + yield path + os.remove(path) @pytest.fixture(scope="module") -def idle_blockchain_policy(alice, bob): - """ - Creates a Policy, in a manner typical of how Alice might do it, with a unique uri (soon to be "label" - see #183) - """ - n = int(constants.NUMBER_OF_URSULAS_IN_NETWORK) - random_label = b'label://' + os.urandom(32) - policy = alice.create_policy(bob, label=random_label, m=3, n=n) - return policy +def test_keystore(): + engine = create_engine('sqlite:///:memory:') + Base.metadata.create_all(engine) + test_keystore = keystore.KeyStore(engine) + yield test_keystore + + + +# +# Policies +# @pytest.fixture(scope="module") @@ -40,20 +69,6 @@ def idle_federated_policy(alice, bob): return policy -@pytest.fixture(scope="module") -def enacted_blockchain_policy(idle_blockchain_policy, ursulas): - # Alice has a policy in mind and knows of enough qualifies Ursulas; she crafts an offer for them. - deposit = constants.NON_PAYMENT(b"0000000") - contract_end_datetime = maya.now() + datetime.timedelta(days=5) - network_middleware = MockRestMiddleware() - - idle_blockchain_policy.make_arrangements(network_middleware, deposit=deposit, expiration=contract_end_datetime, - ursulas=list(ursulas)) - idle_blockchain_policy.enact(network_middleware) # REST call happens here, as does population of TreasureMap. - - return idle_blockchain_policy - - @pytest.fixture(scope="module") def enacted_federated_policy(idle_federated_policy, ursulas): # Alice has a policy in mind and knows of enough qualifies Ursulas; she crafts an offer for them. @@ -70,6 +85,35 @@ def enacted_federated_policy(idle_federated_policy, ursulas): return idle_federated_policy +@pytest.fixture(scope="module") +def idle_blockchain_policy(alice, bob): + """ + Creates a Policy, in a manner typical of how Alice might do it, with a unique uri (soon to be "label" - see #183) + """ + n = int(constants.NUMBER_OF_URSULAS_IN_NETWORK) + random_label = b'label://' + os.urandom(32) + policy = alice.create_policy(bob, label=random_label, m=3, n=n) + return policy + + +@pytest.fixture(scope="module") +def enacted_blockchain_policy(idle_blockchain_policy, ursulas): + # Alice has a policy in mind and knows of enough qualifies Ursulas; she crafts an offer for them. + deposit = constants.NON_PAYMENT(b"0000000") + contract_end_datetime = maya.now() + datetime.timedelta(days=5) + network_middleware = MockRestMiddleware() + + idle_blockchain_policy.make_arrangements(network_middleware, deposit=deposit, expiration=contract_end_datetime, + ursulas=list(ursulas)) + idle_blockchain_policy.enact(network_middleware) # REST call happens here, as does population of TreasureMap. + + return idle_blockchain_policy + + +# +# Alice, Bob, and Capsule +# + @pytest.fixture(scope="module") def alice(ursulas, three_agents): token_agent, miner_agent, policy_agent = three_agents @@ -94,6 +138,19 @@ def bob(): return _bob +@pytest.fixture(scope="module") +def capsule_side_channel(enacted_federated_policy): + signing_keypair = SigningKeypair() + data_source = DataSource(policy_pubkey_enc=enacted_federated_policy.public_key, + signing_keypair=signing_keypair) + message_kit, _signature = data_source.encapsulate_single_message(b"Welcome to the flippering.") + return message_kit, data_source + + +# +# Ursulas +# + @pytest.fixture(scope="module") def ursulas(three_agents): token_agent, miner_agent, policy_agent = three_agents @@ -134,27 +191,100 @@ def mining_ursulas(three_agents): @pytest.fixture(scope="module") -def test_keystore(): - engine = create_engine('sqlite:///:memory:') - Base.metadata.create_all(engine) - test_keystore = keystore.KeyStore(engine) - yield test_keystore +def non_ursula_miners(three_agents): + token_agent, miner_agent, policy_agent = three_agents + etherbase, alice, bob, *all_yall = token_agent.blockchain.interface.w3.eth.accounts + + ursula_addresses = all_yall[:int(constants.NUMBER_OF_URSULAS_IN_NETWORK)] + + _receipts = token_airdrop(token_agent=token_agent, origin=etherbase, + addresses=all_yall, amount=1000000 * constants.M) + + starting_point = constants.URSULA_PORT_SEED + 500 + + _ursulas = make_ursulas(ether_addresses=ursula_addresses, + ursula_starting_port=int(starting_point), + miner_agent=miner_agent, + miners=True, + bare=True) + try: + yield _ursulas + finally: + # Remove the DBs that have been sprayed hither and yon. + with contextlib.suppress(FileNotFoundError): + for port, ursula in enumerate(_ursulas, start=int(starting_point)): + os.remove("test-{}".format(port)) -@pytest.fixture(scope="module") -def capsule_side_channel(enacted_federated_policy): - signing_keypair = SigningKeypair() - data_source = DataSource(policy_pubkey_enc=enacted_federated_policy.public_key, - signing_keypair=signing_keypair) - message_kit, _signature = data_source.encapsulate_single_message(b"Welcome to the flippering.") - return message_kit, data_source +# +# Blockchain +# + +@pytest.fixture(scope='session') +def solidity_compiler(): + """Doing this more than once per session will result in slower test run times.""" + test_contracts_dir = os.path.join(dirname(abspath(contracts.__file__)), 'contracts') + compiler = SolidityCompiler(test_contract_dir=test_contracts_dir) + yield compiler -@pytest.fixture(scope="function") -def tempfile_path(): +@pytest.fixture(scope='module') +def testerchain(solidity_compiler): """ - User is responsible for closing the file given at the path. + https: // github.com / ethereum / eth - tester # available-backends """ - _, path = tempfile.mkstemp() - yield path - os.remove(path) + + temp_registrar = TemporaryEthereumContractRegistry() + + # Configure a custom provider + overrides = {'gas_limit': 4626271} + pyevm_backend = OverridablePyEVMBackend(genesis_overrides=overrides) + + eth_tester = EthereumTester(backend=pyevm_backend, auto_mine_transactions=True) + pyevm_provider = EthereumTesterProvider(ethereum_tester=eth_tester) + + # Use the the custom provider and registrar to init an interface + circumflex = DeployerCircumflex(compiler=solidity_compiler, # freshly recompile + registry=temp_registrar, # use temporary registrar + providers=(pyevm_provider, )) # use custom test provider + + # Create the blockchain + testerchain = TesterBlockchain(interface=circumflex, test_accounts=10) + origin, *everyone = testerchain.interface.w3.eth.accounts + circumflex.deployer_address = origin # Set the deployer address from a freshly created test account + + yield testerchain + + testerchain.sever_connection() + + +@pytest.fixture(scope='module') +def three_agents(testerchain): + """ + Musketeers, if you will. + Launch the big three contracts on provided chain, + make agents for each and return them. + """ + + """Launch all Nucypher ethereum contracts""" + origin, *everybody_else = testerchain.interface.w3.eth.accounts + + token_deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) + token_deployer.arm() + token_deployer.deploy() + + token_agent = token_deployer.make_agent() + + miner_escrow_deployer = MinerEscrowDeployer(token_agent=token_agent, deployer_address=origin) + miner_escrow_deployer.arm() + miner_escrow_deployer.deploy() + + miner_agent = miner_escrow_deployer.make_agent() + + policy_manager_deployer = PolicyManagerDeployer(miner_agent=miner_agent, deployer_address=origin) + policy_manager_deployer.arm() + policy_manager_deployer.deploy() + + policy_agent = policy_manager_deployer.make_agent() + + return token_agent, miner_agent, policy_agent