From 5483f2657cf6c210c28fd963f262dfa3d56d526a Mon Sep 17 00:00:00 2001 From: Joe Matthew Date: Mon, 12 Aug 2024 17:29:40 +0200 Subject: [PATCH] fix: use latest dev versions --- .github/workflows/ci.yaml | 2 +- Makefile | 38 +++------------------------------ base.env | 4 ++-- poetry.lock | 36 ++++++++++++++++++++++++++++++- pyproject.toml | 1 + tests/conftest.py | 16 +++++++++++--- tests/helper.py | 45 ++++++++++++++++++++++++--------------- tests/test_transfer.py | 26 +++++++++++----------- 8 files changed, 97 insertions(+), 71 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 98b4706..f65e7a9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -44,7 +44,7 @@ jobs: run: | ssh-keygen -t ed25519 -f signer_key.pem -N '' chmod 777 signer_key.pem - working-directory: service-node + working-directory: servicenode - name: Set up QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - name: Set up Docker Buildx diff --git a/Makefile b/Makefile index fbb16d1..d533356 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,5 @@ PYTHON_FILES := tests - -.PHONY: check-version -check-version: - @if [ -z "$(VERSION)" ]; then \ - echo "Error: VERSION is not set"; \ - exit 1; \ - fi - @VERSION_FROM_POETRY=$$(poetry version -s) ; \ - if test "$$VERSION_FROM_POETRY" != "$(VERSION)"; then \ - echo "Version mismatch: expected $(VERSION), got $$VERSION_FROM_POETRY" ; \ - exit 1 ; \ - else \ - echo "Version check passed" ; \ - fi - -.PHONY: dist -dist: tar wheel debian +MAX_CONCURRENCY ?= 1 .PHONY: code code: check format lint sort bandit test @@ -54,24 +38,8 @@ bandit-check: .PHONY: test test: - poetry run python3 -m pytest tests + poetry run python3 -m pytest -s -n ${MAX_CONCURRENCY} tests .PHONY: coverage coverage: - poetry run python3 -m pytest --cov-report term-missing --cov=pantos tests - -.PHONY: coverage-postgres -coverage-postgres: - poetry run python3 -m pytest --cov-report term-missing --cov=pantos - -.PHONY: coverage-all -coverage-all: - poetry run python3 -m pytest --cov-report term-missing --cov=pantos tests - -check-swarm-init: - @if [ "$$(docker info --format '{{.Swarm.LocalNodeState}}')" != "active" ]; then \ - echo "Docker is not part of a swarm. Initializing..."; \ - docker swarm init; \ - else \ - echo "Docker is already part of a swarm."; \ - fi + poetry run python3 -m pytest -s -n ${MAX_CONCURRENCY} --cov-report term-missing --cov=pantos tests diff --git a/base.env b/base.env index b82b264..8b5ffb1 100644 --- a/base.env +++ b/base.env @@ -26,7 +26,7 @@ AVALANCHE_TOKEN_PANMATIC=${AVALANCHE_PANMATIC} AVALANCHE_TOKEN_PANSOL=${AVALANCHE_PANSOL} ### BNB ### BNB_ACTIVE=true -BNB_PROVIDER=http://localhost:8546 +BNB_PROVIDER=http://localhost:8${PORT_OFFSET-5}${INSTANCE-1}1 ##### fallback_providers ##### # BNB_FALLBACK_PROVIDER= # BNB_AVERAGE_BLOCK_TIME= @@ -89,7 +89,7 @@ CRONOS_TOKEN_PANMATIC=${CRONOS_PANMATIC} CRONOS_TOKEN_PANSOL=${CRONOS_PANSOL} ### ethereum ### ETHEREUM_ACTIVE=true -ETHEREUM_PROVIDER=http://localhost:8545 +ETHEREUM_PROVIDER=http://localhost:8${PORT_OFFSET-5}${INSTANCE-1}0 ##### fallback_providers ##### # ETHEREUM_FALLBACK_PROVIDER= # ETHEREUM_AVERAGE_BLOCK_TIME= diff --git a/poetry.lock b/poetry.lock index 2b44ead..7b4aa1a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1073,6 +1073,20 @@ docs = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)" lint = ["black (>=23)", "flake8 (==3.8.3)", "isort (>=5.11.0)", "mypy (==0.971)", "pydocstyle (>=5.0.0)", "types-setuptools"] test = ["hypothesis (>=4.43.0)", "mypy (==0.971)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "types-setuptools"] +[[package]] +name = "execnet" +version = "2.1.1" +description = "execnet: rapid multi-Python deployment" +optional = false +python-versions = ">=3.8" +files = [ + {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, + {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, +] + +[package.extras] +testing = ["hatch", "pre-commit", "pytest", "tox"] + [[package]] name = "filelock" version = "3.15.4" @@ -2358,6 +2372,26 @@ files = [ [package.dependencies] pytest = "*" +[[package]] +name = "pytest-xdist" +version = "3.6.1" +description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, + {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, +] + +[package.dependencies] +execnet = ">=2.1" +pytest = ">=7.0.0" + +[package.extras] +psutil = ["psutil (>=3.0)"] +setproctitle = ["setproctitle"] +testing = ["filelock"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -3202,4 +3236,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "846522103bcfc9bea78e1270f68e0746cecbd38d8c85ba6a6ea7664b1b465ae6" +content-hash = "774b7d27db28fe6e667d3726d0fd353390250a7c37213ea38cdef2ed1a196e47" diff --git a/pyproject.toml b/pyproject.toml index 8d18fbc..9e7ec61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ pre-commit = "3.7.1" python = "^3.12" pantos-client-library = "^1.1.4" pytest-ordering = "^0.6" +pytest-xdist = "^3.6.1" [build-system] requires = ["poetry-core"] diff --git a/tests/conftest.py b/tests/conftest.py index 3d03bc9..348455e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,4 @@ +import glob import os import pathlib import random @@ -22,9 +23,18 @@ def stack_id(): return generate_random_string() @pytest.fixture -def keystore(request): - network = request.param - return os.getenv('PANTOS_ETHEREUM_CONTRACTS') + f'/data/{network}/keystore' +def keystore(request, stack_id): + network = request.param if request and request.param else 'eth' + contracts_dir = os.getenv('PANTOS_ETHEREUM_CONTRACTS') + file = f'{contracts_dir}/data/*{stack_id}-1/{network}/keystore' + resolved_path = glob.glob(file) + if not resolved_path: + raise FileNotFoundError(f'Environment path {file} not found') + if len(resolved_path) > 1: + raise FileNotFoundError(f'Multiple keystore files found: {resolved_path}') + with open(resolved_path[0], 'r') as keystore_file: + keystore = keystore_file.read() + return keystore @pytest.fixture def private_key(keystore): diff --git a/tests/helper.py b/tests/helper.py index 8ed81c0..f6ebc0c 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -1,10 +1,8 @@ import glob import os import pathlib -import platform import subprocess import dotenv -import pantos.client as pc import pantos.client.library.configuration as pc_conf def teardown_environment(stack_id = ''): @@ -31,11 +29,28 @@ def configure_nodes(config, stack_id): if not pantos_ethereum_contracts_dir: raise EnvironmentError('PANTOS_ETHEREUM_CONTRACTS environment variable not set') + + # Teardown + if not config: + # Remove Validator Node + validator_node_command = 'make docker-remove' + env_vars = {'STACK_IDENTIFIER': stack_id} + run_command(validator_node_command, pantos_validator_node_dir, env_vars) + + # Remove Service Node + service_node_command = 'make docker-remove' + run_command(service_node_command, pantos_service_node_dir, env_vars) + + # Remove Ethereum Contracts + ethereum_contracts_command = 'make docker-remove' + run_command(ethereum_contracts_command, pantos_ethereum_contracts_dir, env_vars) + + return # Configure Ethereum contracts if 'ethereum_contracts' in config: - ethereum_contracts_command = 'make docker' - env_vars = {'DOCKER_TAG': pantos_ethereum_contracts_version, 'STACK_IDENTIFIER': stack_id} + ethereum_contracts_command = 'make docker-local' + env_vars = {'DOCKER_TAG': pantos_ethereum_contracts_version, 'STACK_IDENTIFIER': stack_id, 'ARGS': '--no-build'} else: ethereum_contracts_command = 'make docker-remove' env_vars = {'STACK_IDENTIFIER': stack_id} @@ -46,7 +61,7 @@ def configure_nodes(config, stack_id): instance_count = config['service_node'].get('instance_count', 1) service_node_command = f'make docker INSTANCE_COUNT="{instance_count}"' # TODO: Allow service nodes to support multiple networks? - env_vars = {'DOCKER_TAG': pantos_service_node_version, 'STACK_IDENTIFIER': stack_id, 'ETHEREUM_NETWORK': f'{stack_id}-1'} + env_vars = {'DOCKER_TAG': pantos_service_node_version, 'STACK_IDENTIFIER': stack_id, 'ETHEREUM_NETWORK': f'{stack_id}-1', 'NO_BUILD': 'true'} else: service_node_command = 'make docker-remove' env_vars = {'STACK_IDENTIFIER': stack_id} @@ -56,30 +71,26 @@ def configure_nodes(config, stack_id): if 'validator_node' in config: instance_count = config['validator_node'].get('instance_count', 1) validator_node_command = f'make docker INSTANCE_COUNT="{instance_count}"' - env_vars = {'DOCKER_TAG': pantos_validator_node_version, 'STACK_IDENTIFIER': stack_id, 'ETHEREUM_NETWORK': f'{stack_id}-1'} + env_vars = {'DOCKER_TAG': pantos_validator_node_version, 'STACK_IDENTIFIER': stack_id, 'ETHEREUM_NETWORK': f'{stack_id}-1', 'NO_BUILD': 'true'} else: validator_node_command = 'make docker-remove' env_vars = {'STACK_IDENTIFIER': stack_id} run_command(validator_node_command, pantos_validator_node_dir, env_vars) - - return setup_environment(stack_id) -def setup_environment(stack_id): +def configure_client(stack_id, instance = 1): if not os.getenv('PANTOS_ETHEREUM_CONTRACTS'): raise EnvironmentError('PANTOS_ETHEREUM_CONTRACTS environment variable not set') contracts_dir = os.getenv('PANTOS_ETHEREUM_CONTRACTS') current_dir = os.path.dirname(os.path.realpath(__file__)) # TODO: Return one library instance per instance from the stack id - for file in [f'{contracts_dir}/data/*{stack_id}-1/eth/all.env', current_dir + 'client-library.env']: + for file in [f'{contracts_dir}/data/*{stack_id}-{instance}/eth/all.env', f'{current_dir}/../base.env']: resolved_path = glob.glob(file) if not resolved_path: - raise FileNotFoundError(f'Environment file {file} not found') - env_file = resolved_path[0] - if not pathlib.Path(env_file).exists(): - raise FileNotFoundError(f'Environment file {env_file}.env not found') - dotenv.load_dotenv(env_file) + raise FileNotFoundError(f'Environment path {file} not found') + for env_file in resolved_path: + if not pathlib.Path(env_file).exists(): + raise FileNotFoundError(f'Environment file {env_file} not found') + dotenv.load_dotenv(env_file) pc_conf.load_config(None, True) - - return pc diff --git a/tests/test_transfer.py b/tests/test_transfer.py index cd9e311..18065a8 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -1,24 +1,28 @@ import decimal +import os import pytest import pantos.client as pc -from helper import configure_nodes, teardown_environment +from helper import configure_client, configure_nodes, teardown_environment @pytest.fixture(scope="module", autouse=True) -def setup_module(request, stack_id): +def setup_module(request, stack_id, worker_id = "gw0"): # Code to set up the environment before any tests in the module print("Setting up module environment") + port_offset = int(worker_id.replace("gw", "")) if worker_id != "master" else 0 + os.environ['PORT_OFFSET'] = str(port_offset) configure_nodes({ - 'ethereum_contracts': {'args': ''}, - 'service_node': {'instance_count': 2}, - 'validator_node': {'instance_count': 2} + 'ethereum_contracts': {'args': '', 'port_group': port_offset}, + 'service_node': {'instance_count': 2, 'port_group': port_offset}, + 'validator_node': {'instance_count': 2, 'port_group': port_offset} }, stack_id) + configure_client(stack_id) request.addfinalizer(lambda: teardown_environment(stack_id)) def test_retrieve_token_balance(receiving_address): try: token_balance = pc.retrieve_token_balance( - pc.Blockchain.POLYGON, + pc.Blockchain.BNB_CHAIN, pc.BlockchainAddress(receiving_address), pc.TokenSymbol('pan')) assert token_balance is not None @@ -26,10 +30,10 @@ def test_retrieve_token_balance(receiving_address): except pc.PantosClientError: pytest.fail("PantosClientError raised") -def test_retrieve_service_node_bids(): +def test_retrieve_service_node_bids(configure): try: - service_node_bids = pc.retrieve_service_node_bids(pc.Blockchain.AVALANCHE, - pc.Blockchain.CRONOS) + service_node_bids = pc.retrieve_service_node_bids(pc.Blockchain.ETHEREUM, + pc.Blockchain.BNB_CHAIN) assert service_node_bids is not None print('Service node bids: {}'.format(service_node_bids)) except pc.PantosClientError: @@ -77,6 +81,4 @@ def test_deploy_pantos_compatible_token(private_key): assert task_id is not None print('Task ID deployment: {}'.format(task_id)) except pc.PantosClientError: - pytest.fail("PantosClientError raised") - - + pytest.fail("PantosClientError raised")