diff --git a/apps/cic-eth-aux/erc20-demurrage-token/MANIFEST.in b/apps/cic-eth-aux/erc20-demurrage-token/MANIFEST.in new file mode 100644 index 00000000..e705e7e1 --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/MANIFEST.in @@ -0,0 +1 @@ +include *requirements.txt diff --git a/apps/cic-eth-aux/erc20-demurrage-token/cic_eth/aux/__init__.py b/apps/cic-eth-aux/erc20-demurrage-token/cic_eth/aux/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/cic-eth/cic_eth/aux/erc20_demurrage_token/__init__.py b/apps/cic-eth-aux/erc20-demurrage-token/cic_eth/aux/erc20_demurrage_token/__init__.py similarity index 96% rename from apps/cic-eth/cic_eth/aux/erc20_demurrage_token/__init__.py rename to apps/cic-eth-aux/erc20-demurrage-token/cic_eth/aux/erc20_demurrage_token/__init__.py index c584218a..9cf1b1f7 100644 --- a/apps/cic-eth/cic_eth/aux/erc20_demurrage_token/__init__.py +++ b/apps/cic-eth-aux/erc20-demurrage-token/cic_eth/aux/erc20_demurrage_token/__init__.py @@ -33,7 +33,7 @@ def get_adjusted_balance(self, token_symbol, amount, timestamp): return c.amount_since(amount, timestamp) -def setup(rpc, config, sender_address=ZERO_ADDRESS): +def aux_setup(rpc, config, sender_address=ZERO_ADDRESS): chain_spec_str = config.get('CIC_CHAIN_SPEC') chain_spec = ChainSpec.from_chain_str(chain_spec_str) token_symbol = config.get('CIC_DEFAULT_TOKEN_SYMBOL') diff --git a/apps/cic-eth-aux/erc20-demurrage-token/requirements.txt b/apps/cic-eth-aux/erc20-demurrage-token/requirements.txt new file mode 100644 index 00000000..0f0a1ac8 --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/requirements.txt @@ -0,0 +1,4 @@ +celery==4.4.7 +erc20-demurrage-token~=0.0.2a3 +cic-eth-registry~=0.5.6a1 +chainlib~=0.0.5a1 diff --git a/apps/cic-eth-aux/erc20-demurrage-token/setup.cfg b/apps/cic-eth-aux/erc20-demurrage-token/setup.cfg new file mode 100644 index 00000000..3e15f156 --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/setup.cfg @@ -0,0 +1,30 @@ +[metadata] +name = cic-eth-aux-erc20-demurrage-token +version = 0.0.2a3 +description = cic-eth tasks supporting erc20 demurrage token +author = Louis Holbrook +author_email = dev@holbrook.no +url = https://gitlab.com/ccicnet/erc20-demurrage-token +keywords = + ethereum + blockchain + cryptocurrency + erc20 +classifiers = + Programming Language :: Python :: 3 + Operating System :: OS Independent + Development Status :: 3 - Alpha + Environment :: No Input/Output (Daemon) + Intended Audience :: Developers + License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) + Topic :: Internet + #Topic :: Blockchain :: EVM +license = GPL3 +licence_files = + LICENSE + +[options] +include_package_data = True +python_requires = >= 3.6 +packages = + cic_eth.aux.erc20_demurrage_token diff --git a/apps/cic-eth-aux/erc20-demurrage-token/setup.py b/apps/cic-eth-aux/erc20-demurrage-token/setup.py new file mode 100644 index 00000000..bc719936 --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +requirements = [] +f = open('requirements.txt', 'r') +while True: + l = f.readline() + if l == '': + break + requirements.append(l.rstrip()) +f.close() + +test_requirements = [] +f = open('test_requirements.txt', 'r') +while True: + l = f.readline() + if l == '': + break + test_requirements.append(l.rstrip()) +f.close() + + +setup( + install_requires=requirements, + tests_require=test_requirements, + ) diff --git a/apps/cic-eth-aux/erc20-demurrage-token/test_requirements.txt b/apps/cic-eth-aux/erc20-demurrage-token/test_requirements.txt new file mode 100644 index 00000000..0faedff4 --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/test_requirements.txt @@ -0,0 +1,12 @@ +pytest==6.0.1 +pytest-celery==0.0.0a1 +pytest-mock==3.3.1 +pytest-cov==2.10.1 +eth-tester==0.5.0b3 +py-evm==0.3.0a20 +SQLAlchemy==1.3.20 +cic-eth~=0.12.0a1 +liveness~=0.0.1a7 +eth-accounts-index==0.0.12a1 +eth-contract-registry==0.5.6a1 +eth-address-index==0.1.2a1 diff --git a/apps/cic-eth-aux/erc20-demurrage-token/tests/conftest.py b/apps/cic-eth-aux/erc20-demurrage-token/tests/conftest.py new file mode 100644 index 00000000..555bfa53 --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/tests/conftest.py @@ -0,0 +1,88 @@ +# external imports +import celery +from chainlib.eth.pytest.fixtures_chain import * +from chainlib.eth.pytest.fixtures_ethtester import * +from cic_eth_registry.pytest.fixtures_contracts import * +from cic_eth_registry.pytest.fixtures_tokens import * +from erc20_demurrage_token.unittest.base import TestTokenDeploy +from erc20_demurrage_token.token import DemurrageToken +from eth_token_index.index import TokenUniqueSymbolIndex +from eth_address_declarator.declarator import AddressDeclarator + +# cic-eth imports +from cic_eth.pytest.fixtures_celery import * +from cic_eth.pytest.fixtures_token import * +from cic_eth.pytest.fixtures_config import * + + +@pytest.fixture(scope='function') +def demurrage_token( + default_chain_spec, + eth_rpc, + token_registry, + contract_roles, + eth_signer, + ): + d = TestTokenDeploy(eth_rpc, token_symbol='BAR', token_name='Bar Token') + nonce_oracle = RPCNonceOracle(contract_roles['CONTRACT_DEPLOYER'], conn=eth_rpc) + c = DemurrageToken(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle) + token_address = d.deploy(eth_rpc, contract_roles['CONTRACT_DEPLOYER'], c, 'SingleNocap') + logg.debug('demurrage token contract "BAR" deployed to {}'.format(token_address)) + + return token_address + + +@pytest.fixture(scope='function') +def demurrage_token_symbol( + default_chain_spec, + eth_rpc, + demurrage_token, + contract_roles, + ): + + c = DemurrageToken(default_chain_spec) + o = c.symbol(demurrage_token, sender_address=contract_roles['CONTRACT_DEPLOYER']) + r = eth_rpc.do(o) + return c.parse_symbol(r) + + +@pytest.fixture(scope='function') +def demurrage_token_declaration( + foo_token_declaration, + ): + return foo_token_declaration + + +@pytest.fixture(scope='function') +def register_demurrage_token( + default_chain_spec, + token_registry, + eth_rpc, + eth_signer, + register_lookups, + contract_roles, + demurrage_token_declaration, + demurrage_token, + address_declarator, + ): + + nonce_oracle = RPCNonceOracle(contract_roles['CONTRACT_DEPLOYER'], eth_rpc) + + c = TokenUniqueSymbolIndex(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.register(token_registry, contract_roles['CONTRACT_DEPLOYER'], demurrage_token) + eth_rpc.do(o) + o = receipt(tx_hash_hex) + r = eth_rpc.do(o) + assert r['status'] == 1 + + nonce_oracle = RPCNonceOracle(contract_roles['TRUSTED_DECLARATOR'], eth_rpc) + c = AddressDeclarator(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.add_declaration(address_declarator, contract_roles['TRUSTED_DECLARATOR'], demurrage_token, demurrage_token_declaration) + + eth_rpc.do(o) + o = receipt(tx_hash_hex) + r = eth_rpc.do(o) + assert r['status'] == 1 + + return token_registry + diff --git a/apps/cic-eth-aux/erc20-demurrage-token/tests/test_demurrage_task.py b/apps/cic-eth-aux/erc20-demurrage-token/tests/test_demurrage_task.py new file mode 100644 index 00000000..75bcf09e --- /dev/null +++ b/apps/cic-eth-aux/erc20-demurrage-token/tests/test_demurrage_task.py @@ -0,0 +1,47 @@ +# standard imports +import logging +import copy +import datetime + +# external imports +import celery + +# cic-eth imports +from cic_eth.aux.erc20_demurrage_token import ( + DemurrageCalculationTask, + aux_setup, + ) + +logg = logging.getLogger() + + +def test_demurrage_calulate_task( + default_chain_spec, + eth_rpc, + cic_registry, + celery_worker, + register_demurrage_token, + demurrage_token_symbol, + contract_roles, + load_config, + ): + + config = copy.copy(load_config) + config.add(str(default_chain_spec), 'CIC_CHAIN_SPEC', exists_ok=True) + config.add(demurrage_token_symbol, 'CIC_DEFAULT_TOKEN_SYMBOL', exists_ok=True) + aux_setup(eth_rpc, load_config, sender_address=contract_roles['CONTRACT_DEPLOYER']) + + since = datetime.datetime.utcnow() - datetime.timedelta(minutes=1) + s = celery.signature( + 'cic_eth.aux.erc20_demurrage_token.get_adjusted_balance', + [ + demurrage_token_symbol, + 1000, + since.timestamp(), + ], + queue=None, + ) + t = s.apply_async() + r = t.get_leaf() + assert t.successful() + assert r == 980 diff --git a/apps/cic-eth/MANIFEST.in b/apps/cic-eth/MANIFEST.in index 739a53c6..5a9554ac 100644 --- a/apps/cic-eth/MANIFEST.in +++ b/apps/cic-eth/MANIFEST.in @@ -1,2 +1,2 @@ -include *requirements.txt +include *requirements.txt config/test/* diff --git a/apps/cic-eth/aux_requirements.txt b/apps/cic-eth/aux_requirements.txt deleted file mode 100644 index c8ecb9bc..00000000 --- a/apps/cic-eth/aux_requirements.txt +++ /dev/null @@ -1 +0,0 @@ -erc20-demurrage-token~=0.0.2a2 diff --git a/apps/cic-eth/cic_eth/pytest/__init__.py b/apps/cic-eth/cic_eth/pytest/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/cic-eth/cic_eth/pytest/fixtures_celery.py b/apps/cic-eth/cic_eth/pytest/fixtures_celery.py index 188f973f..e0f16406 100644 --- a/apps/cic-eth/cic_eth/pytest/fixtures_celery.py +++ b/apps/cic-eth/cic_eth/pytest/fixtures_celery.py @@ -37,7 +37,7 @@ def celery_includes(): 'cic_eth.eth.account', 'cic_eth.callbacks.noop', 'cic_eth.callbacks.http', - 'tests.mock.filter', + 'cic_eth.pytest.mock.filter', ] diff --git a/apps/cic-eth/cic_eth/pytest/fixtures_config.py b/apps/cic-eth/cic_eth/pytest/fixtures_config.py index a4ddedd3..27d7c9cc 100644 --- a/apps/cic-eth/cic_eth/pytest/fixtures_config.py +++ b/apps/cic-eth/cic_eth/pytest/fixtures_config.py @@ -13,7 +13,9 @@ logg = logging.getLogger(__name__) @pytest.fixture(scope='session') def load_config(): - config_dir = os.path.join(root_dir, 'config/test') + config_dir = os.environ.get('CONFINI_DIR') + if config_dir == None: + config_dir = os.path.join(root_dir, 'config/test') conf = confini.Config(config_dir, 'CICTEST') conf.process() logg.debug('config {}'.format(conf)) diff --git a/apps/cic-eth/cic_eth/pytest/fixtures_token.py b/apps/cic-eth/cic_eth/pytest/fixtures_token.py new file mode 100644 index 00000000..51689360 --- /dev/null +++ b/apps/cic-eth/cic_eth/pytest/fixtures_token.py @@ -0,0 +1,19 @@ +# external imports +import pytest +from eth_erc20 import ERC20 + +# TODO: missing dep fixture includes + + +@pytest.fixture(scope='function') +def foo_token_symbol( + default_chain_spec, + foo_token, + eth_rpc, + contract_roles, + ): + + c = ERC20(default_chain_spec) + o = c.symbol(foo_token, sender_address=contract_roles['CONTRACT_DEPLOYER']) + r = eth_rpc.do(o) + return c.parse_symbol(r) diff --git a/apps/cic-eth/tests/mock/__init__.py b/apps/cic-eth/cic_eth/pytest/mock/__init__.py similarity index 100% rename from apps/cic-eth/tests/mock/__init__.py rename to apps/cic-eth/cic_eth/pytest/mock/__init__.py diff --git a/apps/cic-eth/tests/mock/filter.py b/apps/cic-eth/cic_eth/pytest/mock/filter.py similarity index 100% rename from apps/cic-eth/tests/mock/filter.py rename to apps/cic-eth/cic_eth/pytest/mock/filter.py diff --git a/apps/cic-eth/cic_eth/task.py b/apps/cic-eth/cic_eth/task.py index fa542cd2..1af36b09 100644 --- a/apps/cic-eth/cic_eth/task.py +++ b/apps/cic-eth/cic_eth/task.py @@ -1,6 +1,5 @@ # import import time -import requests import logging import uuid @@ -76,7 +75,7 @@ class CriticalSQLAlchemyTask(CriticalTask): class CriticalWeb3Task(CriticalTask): autoretry_for = ( - requests.exceptions.ConnectionError, + ConnectionError, ) safe_gas_threshold_amount = 2000000000 * 60000 * 3 safe_gas_refill_amount = safe_gas_threshold_amount * 5 @@ -86,7 +85,7 @@ class CriticalSQLAlchemyAndWeb3Task(CriticalTask): autoretry_for = ( sqlalchemy.exc.DatabaseError, sqlalchemy.exc.TimeoutError, - requests.exceptions.ConnectionError, + ConnectionError, sqlalchemy.exc.ResourceClosedError, ) safe_gas_threshold_amount = 2000000000 * 60000 * 3 @@ -102,7 +101,7 @@ class CriticalSQLAlchemyAndSignerTask(CriticalTask): class CriticalWeb3AndSignerTask(CriticalTask): autoretry_for = ( - requests.exceptions.ConnectionError, + ConnectionError, ) safe_gas_threshold_amount = 2000000000 * 60000 * 3 safe_gas_refill_amount = safe_gas_threshold_amount * 5 diff --git a/apps/cic-eth/setup.cfg b/apps/cic-eth/setup.cfg index 36c90f14..3ae71014 100644 --- a/apps/cic-eth/setup.cfg +++ b/apps/cic-eth/setup.cfg @@ -39,6 +39,9 @@ packages = cic_eth.callbacks cic_eth.sync cic_eth.check + # should be concealed behind extras "test" if possible (but its not unfortunately) + cic_eth.pytest + cic_eth.pytest.mock scripts = ./scripts/migrate.py diff --git a/apps/cic-eth/setup.py b/apps/cic-eth/setup.py index f13c5fd1..15753d06 100644 --- a/apps/cic-eth/setup.py +++ b/apps/cic-eth/setup.py @@ -12,18 +12,6 @@ while True: f.close() -aux_requirements = [] -f = open('aux_requirements.txt', 'r') -while True: - l = f.readline() - if l == '': - break - aux_requirements.append(l.rstrip()) -f.close() - setup( install_requires=requirements, - extras_require={ - 'aux': aux_requirements, - } ) diff --git a/apps/cic-eth/tests/conftest.py b/apps/cic-eth/tests/conftest.py index 25c10813..a0cc41d3 100644 --- a/apps/cic-eth/tests/conftest.py +++ b/apps/cic-eth/tests/conftest.py @@ -5,6 +5,7 @@ import logging import uuid # external imports +import pytest from eth_erc20 import ERC20 import redis @@ -22,6 +23,7 @@ from cic_eth.pytest.fixtures_celery import * from cic_eth.pytest.fixtures_database import * from cic_eth.pytest.fixtures_role import * from cic_eth.pytest.fixtures_contract import * +from cic_eth.pytest.fixtures_token import * from chainlib.eth.pytest import * from eth_contract_registry.pytest import * from cic_eth_registry.pytest.fixtures_contracts import * @@ -37,20 +39,6 @@ def api( return Api(chain_str, queue=None, callback_param='foo') -@pytest.fixture(scope='function') -def foo_token_symbol( - default_chain_spec, - foo_token, - eth_rpc, - contract_roles, - ): - - c = ERC20(default_chain_spec) - o = c.symbol(foo_token, sender_address=contract_roles['CONTRACT_DEPLOYER']) - r = eth_rpc.do(o) - return c.parse_symbol(r) - - @pytest.fixture(scope='function') def default_token( foo_token, diff --git a/apps/cic-eth/tests/task/api/test_list.py b/apps/cic-eth/tests/task/api/test_list.py index a861a42b..2da3ddac 100644 --- a/apps/cic-eth/tests/task/api/test_list.py +++ b/apps/cic-eth/tests/task/api/test_list.py @@ -110,7 +110,7 @@ def test_list_tx( logg.debug('r {}'.format(r)) # test the api - t = api.list(agent_roles['ALICE'], external_task='tests.mock.filter.filter') + t = api.list(agent_roles['ALICE'], external_task='cic_eth.pytest.mock.filter.filter') r = t.get_leaf() assert t.successful()