From 70a0f9f216090f21966ec2e8c0b8cfb03caf4d44 Mon Sep 17 00:00:00 2001 From: Vladimir Avdeev Date: Thu, 27 Oct 2022 08:43:20 +0300 Subject: [PATCH] Remove neofs-keywords submodule Signed-off-by: Vladimir Avdeev --- .gitmodules | 4 - pytest_tests/helpers/remote_process.py | 2 +- pytest_tests/requirements.txt | 2 +- pytest_tests/testsuites/acl/conftest.py | 15 +- .../acl/storage_group/test_storagegroup.py | 42 ++++- pytest_tests/testsuites/conftest.py | 33 ++-- .../testsuites/container/test_container.py | 4 +- .../testsuites/object/test_object_api.py | 6 +- .../testsuites/payment/test_balance.py | 12 +- .../services/s3_gate/test_s3_gate.py | 6 +- .../services/s3_gate/test_s3_object.py | 31 +++- .../testsuites/services/test_http_gate.py | 4 +- .../test_object_session_token.py | 4 +- robot/resources/lib/python_keywords/epoch.py | 73 ++++---- .../lib/python_keywords/node_management.py | 4 +- .../lib/python_keywords/payment_neogo.py | 175 ++++++++++-------- 16 files changed, 246 insertions(+), 171 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index ef40c8c7..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "neofs-keywords"] - path = neofs-keywords - url = ssh://git@github.com/nspcc-dev/neofs-keywords.git - ignore = all diff --git a/pytest_tests/helpers/remote_process.py b/pytest_tests/helpers/remote_process.py index 1f803c87..35daad68 100644 --- a/pytest_tests/helpers/remote_process.py +++ b/pytest_tests/helpers/remote_process.py @@ -4,8 +4,8 @@ import uuid from typing import Optional import allure -from neofs_testlib.shell.interfaces import CommandOptions from neofs_testlib.shell import Shell +from neofs_testlib.shell.interfaces import CommandOptions from tenacity import retry, stop_after_attempt, wait_fixed diff --git a/pytest_tests/requirements.txt b/pytest_tests/requirements.txt index 0b08afbf..bcfc4a80 100644 --- a/pytest_tests/requirements.txt +++ b/pytest_tests/requirements.txt @@ -35,7 +35,7 @@ neo-mamba==0.10.0 neo3crypto==0.2.1 neo3vm==0.9.0 neo3vm-stubs==0.9.0 -neofs-testlib==0.2.1 +neofs-testlib==0.2.2 netaddr==0.8.0 orjson==3.6.8 packaging==21.3 diff --git a/pytest_tests/testsuites/acl/conftest.py b/pytest_tests/testsuites/acl/conftest.py index 2acd5d16..304a3d96 100644 --- a/pytest_tests/testsuites/acl/conftest.py +++ b/pytest_tests/testsuites/acl/conftest.py @@ -1,3 +1,5 @@ +import os +import uuid from dataclasses import dataclass from typing import Dict, List, Optional @@ -10,12 +12,13 @@ from common import ( STORAGE_WALLET_CONFIG, STORAGE_WALLET_PATH, WALLET_CONFIG, + WALLET_PASS, ) from file_helper import generate_file +from neofs_testlib.utils.wallet import init_wallet from python_keywords.acl import EACLRole from python_keywords.container import create_container from python_keywords.neofs_verbs import put_object -from wallet import init_wallet from wellknown_acl import PUBLIC_ACL OBJECT_COUNT = 5 @@ -40,14 +43,20 @@ class Wallets: @pytest.fixture(scope="module") def wallets(prepare_wallet_and_deposit): + other_wallets_paths = [ + os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") for _ in range(2) + ] + for other_wallet_path in other_wallets_paths: + init_wallet(other_wallet_path, WALLET_PASS) + yield Wallets( wallets={ EACLRole.USER: [ Wallet(wallet_path=prepare_wallet_and_deposit, config_path=WALLET_CONFIG) ], EACLRole.OTHERS: [ - Wallet(wallet_path=init_wallet(ASSETS_DIR)[0], config_path=WALLET_CONFIG), - Wallet(wallet_path=init_wallet(ASSETS_DIR)[0], config_path=WALLET_CONFIG), + Wallet(wallet_path=other_wallet_path, config_path=WALLET_CONFIG) + for other_wallet_path in other_wallets_paths ], EACLRole.SYSTEM: [ Wallet(wallet_path=IR_WALLET_PATH, config_path=IR_WALLET_CONFIG), diff --git a/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py b/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py index 7724125d..519dbc6e 100644 --- a/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py +++ b/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py @@ -1,3 +1,5 @@ +import os +import uuid import logging from typing import Optional @@ -11,11 +13,13 @@ from common import ( IR_WALLET_PASS, IR_WALLET_PATH, SIMPLE_OBJ_SIZE, + WALLET_PASS, ) from epoch import tick_epoch from file_helper import generate_file from grpc_responses import OBJECT_ACCESS_DENIED, OBJECT_NOT_FOUND from neofs_testlib.shell import Shell +from neofs_testlib.utils.wallet import init_wallet from python_keywords.acl import ( EACLAccess, EACLOperation, @@ -27,7 +31,7 @@ from python_keywords.acl import ( ) from python_keywords.container import create_container from python_keywords.neofs_verbs import put_object -from python_keywords.payment_neogo import neofs_deposit, transfer_mainnet_gas +from python_keywords.payment_neogo import deposit_gas, transfer_gas from python_keywords.storage_group import ( delete_storagegroup, get_storagegroup, @@ -36,7 +40,6 @@ from python_keywords.storage_group import ( verify_get_storage_group, verify_list_storage_group, ) -from wallet import init_wallet logger = logging.getLogger("NeoLogger") deposit = 30 @@ -50,12 +53,24 @@ deposit = 30 @pytest.mark.storage_group class TestStorageGroup: @pytest.fixture(autouse=True) - def prepare_two_wallets(self, prepare_wallet_and_deposit): + def prepare_two_wallets(self, prepare_wallet_and_deposit, client_shell): self.main_wallet = prepare_wallet_and_deposit - self.other_wallet, _, _ = init_wallet(ASSETS_DIR) + self.other_wallet = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") + init_wallet(self.other_wallet, WALLET_PASS) if not FREE_STORAGE: - transfer_mainnet_gas(self.other_wallet, 31) - neofs_deposit(self.other_wallet, 30) + deposit = 30 + transfer_gas( + shell=client_shell, + amount=deposit + 1, + wallet_to_path=self.other_wallet, + wallet_to_password=WALLET_PASS, + ) + deposit_gas( + shell=client_shell, + amount=deposit, + wallet_from_path=self.other_wallet, + wallet_from_password=WALLET_PASS, + ) @allure.title("Test Storage Group in Private Container") def test_storagegroup_basic_private_container(self, client_shell, object_size): @@ -226,8 +241,19 @@ class TestStorageGroup: that System key is granted to make all operations except PUT and DELETE. """ if not FREE_STORAGE: - transfer_mainnet_gas(IR_WALLET_PATH, deposit + 1, wallet_password=IR_WALLET_PASS) - neofs_deposit(IR_WALLET_PATH, deposit, wallet_password=IR_WALLET_PASS) + deposit = 30 + transfer_gas( + shell=shell, + amount=deposit + 1, + wallet_to_path=IR_WALLET_PATH, + wallet_to_password=IR_WALLET_PASS, + ) + deposit_gas( + shell=shell, + amount=deposit, + wallet_from_path=IR_WALLET_PATH, + wallet_from_password=IR_WALLET_PASS, + ) storage_group = put_storagegroup(wallet, cid, obj_list) with pytest.raises(Exception, match=OBJECT_ACCESS_DENIED): put_storagegroup(IR_WALLET_PATH, cid, obj_list, wallet_config=IR_WALLET_CONFIG) diff --git a/pytest_tests/testsuites/conftest.py b/pytest_tests/testsuites/conftest.py index f935896e..f633683e 100644 --- a/pytest_tests/testsuites/conftest.py +++ b/pytest_tests/testsuites/conftest.py @@ -1,25 +1,20 @@ import logging import os import shutil +import uuid from datetime import datetime import allure import pytest -import wallet import yaml from binary_version_helper import get_local_binaries_versions, get_remote_binaries_versions -from common import ( - ASSETS_DIR, - FREE_STORAGE, - HOSTING_CONFIG_FILE, - MAINNET_WALLET_PATH, - NEOFS_NETMAP_DICT, -) +from common import ASSETS_DIR, FREE_STORAGE, HOSTING_CONFIG_FILE, NEOFS_NETMAP_DICT, WALLET_PASS from env_properties import save_env_properties from neofs_testlib.hosting import Hosting from neofs_testlib.reporter import AllureHandler, get_reporter from neofs_testlib.shell import LocalShell, Shell -from payment_neogo import neofs_deposit, transfer_mainnet_gas +from neofs_testlib.utils.wallet import init_wallet +from payment_neogo import deposit_gas, transfer_gas from python_keywords.node_management import node_healthcheck logger = logging.getLogger("NeoLogger") @@ -112,14 +107,24 @@ def run_health_check(collect_logs, hosting: Hosting): @pytest.fixture(scope="session") @allure.title("Prepare wallet and deposit") -def prepare_wallet_and_deposit(prepare_tmp_dir): - wallet_path, address, _ = wallet.init_wallet(ASSETS_DIR) - logger.info(f"Init wallet: {wallet_path}, address: {address}") +def prepare_wallet_and_deposit(client_shell, prepare_tmp_dir): + wallet_path = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") + init_wallet(wallet_path, WALLET_PASS) allure.attach.file(wallet_path, os.path.basename(wallet_path), allure.attachment_type.JSON) if not FREE_STORAGE: deposit = 30 - transfer_mainnet_gas(wallet_path, deposit + 1, wallet_path=MAINNET_WALLET_PATH) - neofs_deposit(wallet_path, deposit) + transfer_gas( + shell=client_shell, + amount=deposit + 1, + wallet_to_path=wallet_path, + wallet_to_password=WALLET_PASS, + ) + deposit_gas( + shell=client_shell, + amount=deposit, + wallet_from_path=wallet_path, + wallet_from_password=WALLET_PASS, + ) return wallet_path diff --git a/pytest_tests/testsuites/container/test_container.py b/pytest_tests/testsuites/container/test_container.py index fc74f383..16d1a863 100644 --- a/pytest_tests/testsuites/container/test_container.py +++ b/pytest_tests/testsuites/container/test_container.py @@ -58,7 +58,7 @@ def test_container_creation(client_shell, prepare_wallet_and_deposit, name): with allure.step("Delete container and check it was deleted"): delete_container(wallet, cid, shell=client_shell) - tick_epoch() + tick_epoch(shell=client_shell) wait_for_container_deletion(wallet, cid, shell=client_shell) @@ -92,5 +92,5 @@ def test_container_creation_deletion_parallel(client_shell, prepare_wallet_and_d with allure.step("Delete containers and check they were deleted"): for cid in cids: delete_container(wallet, cid, shell=client_shell) - tick_epoch() + tick_epoch(shell=client_shell) wait_for_container_deletion(wallet, cid, shell=client_shell) diff --git a/pytest_tests/testsuites/object/test_object_api.py b/pytest_tests/testsuites/object/test_object_api.py index c2251793..f71b67ff 100644 --- a/pytest_tests/testsuites/object/test_object_api.py +++ b/pytest_tests/testsuites/object/test_object_api.py @@ -151,7 +151,7 @@ def test_object_api(prepare_wallet_and_deposit, client_shell, request, object_si wallet_path=wallet, cid=cid, oid_ts=tombstone_h, oid=oids[1], shell=client_shell ) - tick_epoch() + tick_epoch(shell=client_shell) sleep(CLEANUP_TIMEOUT) with allure.step("Get objects and check errors"): @@ -180,7 +180,7 @@ def test_object_api_lifetime(prepare_wallet_and_deposit, client_shell, request, file_path = generate_file(object_size) file_hash = get_file_hash(file_path) - epoch = get_epoch() + epoch = get_epoch(shell=client_shell) oid = put_object(wallet, file_path, cid, shell=client_shell, expire_at=epoch + 1) got_file = get_object(wallet, cid, oid, shell=client_shell) @@ -188,7 +188,7 @@ def test_object_api_lifetime(prepare_wallet_and_deposit, client_shell, request, with allure.step("Tick two epochs"): for _ in range(2): - tick_epoch() + tick_epoch(shell=client_shell) # Wait for GC, because object with expiration is counted as alive until GC removes it wait_for_gc_pass_on_storage_nodes() diff --git a/pytest_tests/testsuites/payment/test_balance.py b/pytest_tests/testsuites/payment/test_balance.py index ab66419c..e690c845 100644 --- a/pytest_tests/testsuites/payment/test_balance.py +++ b/pytest_tests/testsuites/payment/test_balance.py @@ -1,13 +1,13 @@ import logging import os +import uuid import allure import pytest import yaml -from common import ASSETS_DIR, FREE_STORAGE, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG +from common import ASSETS_DIR, FREE_STORAGE, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG, WALLET_PASS from neofs_testlib.cli import NeofsCli -from python_keywords.payment_neogo import _address_from_wallet -from wallet import init_wallet +from neofs_testlib.utils.wallet import get_last_address_from_wallet, init_wallet logger = logging.getLogger("NeoLogger") DEPOSIT_AMOUNT = 30 @@ -19,8 +19,10 @@ class TestBalanceAccounting: @pytest.fixture(autouse=True) def prepare_two_wallets(self, prepare_wallet_and_deposit): self.user_wallet = prepare_wallet_and_deposit - self.address = _address_from_wallet(self.user_wallet, "") - _, self.another_address, _ = init_wallet(ASSETS_DIR) + self.address = get_last_address_from_wallet(self.user_wallet, WALLET_PASS) + another_wallet = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") + init_wallet(another_wallet, WALLET_PASS) + self.another_address = get_last_address_from_wallet(another_wallet, WALLET_PASS) @allure.title("Test balance request with wallet and address") def test_balance_wallet_address(self, client_shell): diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py index 41735225..78f2d03e 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py @@ -66,7 +66,7 @@ class TestS3Gate(TestS3GateBase): s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket) @allure.title("Test S3 Bucket API") - def test_s3_buckets(self): + def test_s3_buckets(self, client_shell): """ Test base S3 Bucket API (Create/List/Head/Delete). """ @@ -110,7 +110,7 @@ class TestS3Gate(TestS3GateBase): with allure.step(f"Delete empty bucket {bucket_2}"): s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket_2) - tick_epoch() + tick_epoch(shell=client_shell) with allure.step(f"Check bucket {bucket_2} deleted"): with pytest.raises(Exception, match=r".*Not Found.*"): @@ -126,7 +126,7 @@ class TestS3Gate(TestS3GateBase): with allure.step(f"Delete bucket {bucket_1}"): s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket_1) - tick_epoch() + tick_epoch(shell=client_shell) with allure.step(f"Check bucket {bucket_1} deleted"): with pytest.raises(Exception, match=r".*Not Found.*"): diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py index 0ae380b9..184b15ee 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py @@ -5,12 +5,12 @@ from random import sample import allure import pytest -from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, FREE_STORAGE, SIMPLE_OBJ_SIZE +from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, FREE_STORAGE, SIMPLE_OBJ_SIZE, WALLET_PASS from data_formatters import get_wallet_public_key from file_helper import concat_files, generate_file, generate_file_with_content, get_file_hash -from python_keywords.payment_neogo import neofs_deposit, transfer_mainnet_gas +from python_keywords.payment_neogo import deposit_gas, transfer_gas from s3_helper import assert_object_lock_mode, check_objects_in_bucket, set_bucket_versioning -from wallet import init_wallet +from neofs_testlib.utils.wallet import init_wallet from steps import s3_gate_bucket, s3_gate_object from steps.aws_cli_client import AwsCliClient @@ -660,14 +660,27 @@ class TestS3GateObject(TestS3GateBase): ], "Tags must be the same" @pytest.fixture - def prepare_two_wallets(self, prepare_wallet_and_deposit): + def prepare_two_wallets(self, prepare_wallet_and_deposit, client_shell): self.main_wallet = prepare_wallet_and_deposit - self.main_public_key = get_wallet_public_key(self.main_wallet, "") - self.other_wallet, _, _ = init_wallet(ASSETS_DIR) - self.other_public_key = get_wallet_public_key(self.other_wallet, "") + self.main_public_key = get_wallet_public_key(self.main_wallet, WALLET_PASS) + self.other_wallet = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") + init_wallet(self.other_wallet, WALLET_PASS) + self.other_public_key = get_wallet_public_key(self.other_wallet, WALLET_PASS) + if not FREE_STORAGE: - transfer_mainnet_gas(self.other_wallet, 31) - neofs_deposit(self.other_wallet, 30) + deposit = 30 + transfer_gas( + shell=client_shell, + amount=deposit + 1, + wallet_to_path=self.other_wallet, + wallet_to_password=WALLET_PASS, + ) + deposit_gas( + shell=client_shell, + amount=deposit, + wallet_from_path=self.other_wallet, + wallet_from_password=WALLET_PASS, + ) @allure.title("Test S3: put object with ACL") @pytest.mark.parametrize("bucket_versioning", ["ENABLED", "SUSPENDED"]) diff --git a/pytest_tests/testsuites/services/test_http_gate.py b/pytest_tests/testsuites/services/test_http_gate.py index ce64f099..314ab7e9 100644 --- a/pytest_tests/testsuites/services/test_http_gate.py +++ b/pytest_tests/testsuites/services/test_http_gate.py @@ -154,7 +154,7 @@ class TestHttpGate: file_path = generate_file() oids = [] - curr_epoch = get_epoch() + curr_epoch = get_epoch(client_shell) epochs = (curr_epoch, curr_epoch + 1, curr_epoch + 2, curr_epoch + 100) for epoch in epochs: @@ -170,7 +170,7 @@ class TestHttpGate: get_via_http_gate(cid=cid, oid=oid) for expired_objects, not_expired_objects in [(oids[:1], oids[1:]), (oids[:2], oids[2:])]: - tick_epoch() + tick_epoch(shell=client_shell) # Wait for GC, because object with expiration is counted as alive until GC removes it wait_for_gc_pass_on_storage_nodes() diff --git a/pytest_tests/testsuites/session_token/test_object_session_token.py b/pytest_tests/testsuites/session_token/test_object_session_token.py index 10b55d7a..1dd44d9c 100644 --- a/pytest_tests/testsuites/session_token/test_object_session_token.py +++ b/pytest_tests/testsuites/session_token/test_object_session_token.py @@ -6,7 +6,7 @@ from common import COMPLEX_OBJ_SIZE, NEOFS_NETMAP_DICT, SIMPLE_OBJ_SIZE from file_helper import generate_file from grpc_responses import SESSION_NOT_FOUND from neofs_testlib.shell import Shell -from payment_neogo import _address_from_wallet +from neofs_testlib.utils.wallet import get_last_address_from_wallet from python_keywords.container import create_container from python_keywords.neofs_verbs import ( delete_object, @@ -39,7 +39,7 @@ def test_object_session_token(prepare_wallet_and_deposit, client_shell: Shell, o with allure.step("Init wallet"): wallet = prepare_wallet_and_deposit - address = _address_from_wallet(wallet, "") + address = get_last_address_from_wallet(wallet, "") with allure.step("Nodes Settlements"): ( diff --git a/robot/resources/lib/python_keywords/epoch.py b/robot/resources/lib/python_keywords/epoch.py index 9b5d18cb..24acbef2 100644 --- a/robot/resources/lib/python_keywords/epoch.py +++ b/robot/resources/lib/python_keywords/epoch.py @@ -1,60 +1,63 @@ -#!/usr/bin/python3.9 +import json import logging +from time import sleep import allure -import contract -import wrappers from common import ( IR_WALLET_PASS, IR_WALLET_PATH, + MAINNET_BLOCK_TIME, MORPH_ENDPOINT, NEOFS_ADM_CONFIG_PATH, NEOFS_ADM_EXEC, + NEOGO_EXECUTABLE, ) +from neofs_testlib.cli import NeofsAdm, NeoGo +from neofs_testlib.shell import Shell +from neofs_testlib.utils.wallet import get_last_address_from_wallet +from payment_neogo import get_contract_hash +from utility import parse_time logger = logging.getLogger("NeoLogger") @allure.step("Get Epoch") -def get_epoch(): - epoch = int( - contract.testinvoke_contract( - contract.get_netmap_contract_hash(MORPH_ENDPOINT), "epoch", MORPH_ENDPOINT - ) +def get_epoch(shell: Shell): + neogo = NeoGo(shell=shell, neo_go_exec_path=NEOGO_EXECUTABLE) + out = neogo.contract.testinvokefunction( + scripthash=get_contract_hash("netmap.neofs", shell=shell), + method="epoch", + rpc_endpoint=MORPH_ENDPOINT, ) - logger.info(f"Got epoch {epoch}") - return epoch + return int(json.loads(out.stdout.replace("\n", ""))["stack"][0]["value"]) @allure.step("Tick Epoch") -def tick_epoch(): +def tick_epoch(shell: Shell): if NEOFS_ADM_EXEC and NEOFS_ADM_CONFIG_PATH: # If neofs-adm is available, then we tick epoch with it (to be consistent with UAT tests) - cmd = f"{NEOFS_ADM_EXEC} morph force-new-epoch -c {NEOFS_ADM_CONFIG_PATH}" - logger.info(f"Executing shell command: {cmd}") - out = "" - err = "" - try: - out = wrappers.run_sh(cmd) - logger.info(f"Command completed with output: {out}") - except Exception as exc: - logger.error(exc) - err = str(exc) - raise RuntimeError("Failed to tick epoch") from exc - finally: - allure.attach( - (f"COMMAND: {cmd}\n" f"OUTPUT:\n {out}\n" f"ERROR: {err}\n"), - "Tick Epoch", - allure.attachment_type.TEXT, - ) + neofsadm = NeofsAdm( + shell=shell, neofs_adm_exec_path=NEOFS_ADM_EXEC, config_file=NEOFS_ADM_CONFIG_PATH + ) + neofsadm.morph.force_new_epoch() return # Otherwise we tick epoch using transaction - cur_epoch = get_epoch() - return contract.invoke_contract_multisig( - contract.get_netmap_contract_hash(MORPH_ENDPOINT), - f"newEpoch int:{cur_epoch + 1}", - IR_WALLET_PATH, - IR_WALLET_PASS, - MORPH_ENDPOINT, + cur_epoch = get_epoch(shell) + + ir_address = get_last_address_from_wallet(IR_WALLET_PATH, IR_WALLET_PASS) + + neogo = NeoGo(shell, neo_go_exec_path=NEOGO_EXECUTABLE) + neogo.contract.invokefunction( + wallet=IR_WALLET_PATH, + wallet_password=IR_WALLET_PASS, + scripthash=get_contract_hash("netmap.neofs", shell=shell), + method="newEpoch", + arguments=f"int:{cur_epoch + 1}", + multisig_hash=f"{ir_address}:Global", + address=ir_address, + rpc_endpoint=MORPH_ENDPOINT, + force=True, + gas=1, ) + sleep(parse_time(MAINNET_BLOCK_TIME)) diff --git a/robot/resources/lib/python_keywords/node_management.py b/robot/resources/lib/python_keywords/node_management.py index bb379ff4..e71bf8f6 100644 --- a/robot/resources/lib/python_keywords/node_management.py +++ b/robot/resources/lib/python_keywords/node_management.py @@ -174,7 +174,7 @@ def exclude_node_from_network_map( node_set_status(hosting, node_to_exclude, status="offline") time.sleep(parse_time(MORPH_BLOCK_TIME)) - tick_epoch() + tick_epoch(shell=shell) snapshot = get_netmap_snapshot(node_name=alive_node, shell=shell) assert ( @@ -189,7 +189,7 @@ def include_node_to_network_map( node_set_status(hosting, node_to_include, status="online") time.sleep(parse_time(MORPH_BLOCK_TIME)) - tick_epoch() + tick_epoch(shell=shell) check_node_in_map(node_to_include, shell, alive_node) diff --git a/robot/resources/lib/python_keywords/payment_neogo.py b/robot/resources/lib/python_keywords/payment_neogo.py index 52b840b4..c2d92709 100644 --- a/robot/resources/lib/python_keywords/payment_neogo.py +++ b/robot/resources/lib/python_keywords/payment_neogo.py @@ -1,15 +1,14 @@ -#!/usr/bin/python3 - +import base64 +import json import logging import re import time +from typing import Optional import allure -import contract -import converters -import rpc_client from common import ( GAS_HASH, + MAINNET_BLOCK_TIME, MAINNET_SINGLE_ADDR, MAINNET_WALLET_PASS, MAINNET_WALLET_PATH, @@ -18,10 +17,13 @@ from common import ( NEOFS_CONTRACT, NEOGO_EXECUTABLE, ) -from converters import load_wallet -from neo3 import wallet -from wallet import nep17_transfer -from wrappers import run_sh_with_passwd_contract +from neo3 import wallet as neo3_wallet +from neofs_testlib.blockchain import RPCClient +from neofs_testlib.cli import NeoGo +from neofs_testlib.shell import Shell +from neofs_testlib.utils.converters import contract_hash_to_address +from neofs_testlib.utils.wallet import get_last_address_from_wallet +from utility import parse_time logger = logging.getLogger("NeoLogger") @@ -30,26 +32,46 @@ TX_PERSIST_TIMEOUT = 15 # seconds ASSET_POWER_MAINCHAIN = 10**8 ASSET_POWER_SIDECHAIN = 10**12 -morph_rpc_cli = rpc_client.RPCClient(MORPH_ENDPOINT) -mainnet_rpc_cli = rpc_client.RPCClient(NEO_MAINNET_ENDPOINT) +morph_rpc_client = RPCClient(MORPH_ENDPOINT) +mainnet_rpc_client = RPCClient(NEO_MAINNET_ENDPOINT) + + +def get_nns_contract_hash() -> str: + rpc_client = RPCClient(MORPH_ENDPOINT) + return rpc_client.get_contract_state(1)["hash"] + + +def get_contract_hash(resolve_name: str, shell: Shell) -> str: + nns_contract_hash = get_nns_contract_hash() + neogo = NeoGo(shell=shell, neo_go_exec_path=NEOGO_EXECUTABLE) + out = neogo.contract.testinvokefunction( + scripthash=nns_contract_hash, + method="resolve", + arguments=f"string:{resolve_name} int:16", + rpc_endpoint=MORPH_ENDPOINT, + ) + stack_data = json.loads(out.stdout.replace("\n", ""))["stack"][0]["value"] + return bytes.decode(base64.b64decode(stack_data[0]["value"])) @allure.step("Withdraw Mainnet Gas") -def withdraw_mainnet_gas(wlt: str, amount: int): - address = _address_from_wallet(wlt, EMPTY_PASSWORD) - scripthash = wallet.Account.address_to_script_hash(address) +def withdraw_mainnet_gas(shell: Shell, wlt: str, amount: int): + address = get_last_address_from_wallet(wlt, EMPTY_PASSWORD) + scripthash = neo3_wallet.Account.address_to_script_hash(address) - cmd = ( - f"{NEOGO_EXECUTABLE} contract invokefunction -w {wlt} -a {address} " - f"-r {NEO_MAINNET_ENDPOINT} {NEOFS_CONTRACT} withdraw {scripthash} " - f"int:{amount} -- {scripthash}:Global" + neogo = NeoGo(shell=shell, neo_go_exec_path=NEOGO_EXECUTABLE) + out = neogo.contract.invokefunction( + wallet=wlt, + address=address, + rpc_endpoint=NEO_MAINNET_ENDPOINT, + scripthash=NEOFS_CONTRACT, + method="withdraw", + arguments=f"{scripthash} int:{amount}", + multisig_hash=f"{scripthash}:Global", + wallet_password="", ) - logger.info(f"Executing command: {cmd}") - raw_out = run_sh_with_passwd_contract("", cmd, expect_confirmation=True) - out = raw_out.decode("utf-8") - logger.info(f"Command completed with output: {out}") - m = re.match(r"^Sent invocation transaction (\w{64})$", out) + m = re.match(r"^Sent invocation transaction (\w{64})$", out.stdout) if m is None: raise Exception("Can not get Tx.") tx = m.group(1) @@ -69,7 +91,7 @@ def transaction_accepted(tx_id: str): try: for _ in range(0, TX_PERSIST_TIMEOUT): time.sleep(1) - resp = mainnet_rpc_cli.get_transaction_height(tx_id) + resp = mainnet_rpc_client.get_transaction_height(tx_id) if resp is not None: logger.info(f"TX is accepted in block: {resp}") return True @@ -80,16 +102,17 @@ def transaction_accepted(tx_id: str): @allure.step("Get NeoFS Balance") -def get_balance(wallet_path: str): +def get_balance(shell: Shell, wallet_path: str, wallet_password: str = ""): """ This function returns NeoFS balance for given wallet. """ - wlt = load_wallet(wallet_path) - acc = wlt.accounts[-1] + with open(wallet_path) as wallet_file: + wallet = neo3_wallet.Wallet.from_json(json.load(wallet_file), password=wallet_password) + acc = wallet.accounts[-1] payload = [{"type": "Hash160", "value": str(acc.script_hash)}] try: - resp = morph_rpc_cli.invoke_function( - contract.get_balance_contract_hash(MORPH_ENDPOINT), "balanceOf", payload + resp = morph_rpc_client.invoke_function( + get_contract_hash("balance.neofs", shell=shell), "balanceOf", payload ) logger.info(f"Got response \n{resp}") value = int(resp["stack"][0]["value"]) @@ -99,81 +122,79 @@ def get_balance(wallet_path: str): raise out -@allure.step("Transfer Mainnet Gas") -def transfer_mainnet_gas( - wallet_to: str, +@allure.title("Transfer Gas") +def transfer_gas( + shell: Shell, amount: int, - wallet_password: str = EMPTY_PASSWORD, - wallet_path: str = MAINNET_WALLET_PATH, + wallet_from_path: str = MAINNET_WALLET_PATH, + wallet_from_password: str = MAINNET_WALLET_PASS, + address_from: str = MAINNET_SINGLE_ADDR, + address_to: Optional[str] = None, + wallet_to_path: Optional[str] = None, + wallet_to_password: Optional[str] = None, ): """ This function transfer GAS in main chain from mainnet wallet to the provided wallet. If the wallet contains more than one address, the assets will be transferred to the last one. Args: - wallet_to (str): the path to the wallet to transfer assets to - amount (int): amount of gas to transfer - wallet_password (optional, str): password of the wallet; it is + shell: Shell instance. + wallet_from_password: password of the wallet; it is required to decode the wallet and extract its addresses - wallet_path (str): path to chain node wallet + wallet_from_path: path to chain node wallet + address_from: the address of the wallet to transfer assets from + wallet_to_path: the path to the wallet to transfer assets to + wallet_to_password: the password to the wallet to transfer assets to + address_to: the address of the wallet to transfer assets to + amount: amount of gas to transfer Returns: (void) """ - address_to = _address_from_wallet(wallet_to, wallet_password) + address_to = address_to or get_last_address_from_wallet(wallet_to_path, wallet_to_password) - txid = nep17_transfer( - wallet_path, - address_to, - amount, - NEO_MAINNET_ENDPOINT, - wallet_pass=MAINNET_WALLET_PASS, - addr_from=MAINNET_SINGLE_ADDR, + neogo = NeoGo(shell, neo_go_exec_path=NEOGO_EXECUTABLE) + out = neogo.nep17.transfer( + rpc_endpoint=NEO_MAINNET_ENDPOINT, + wallet=wallet_from_path, + wallet_password=wallet_from_password, + amount=amount, + from_address=address_from, + to_address=address_to, + token="GAS", + force=True, ) + txid = out.stdout.strip().split("\n")[-1] + if len(txid) != 64: + raise Exception("Got no TXID after run the command") if not transaction_accepted(txid): raise AssertionError(f"TX {txid} hasn't been processed") + time.sleep(parse_time(MAINNET_BLOCK_TIME)) @allure.step("NeoFS Deposit") -def neofs_deposit(wallet_to: str, amount: int, wallet_password: str = EMPTY_PASSWORD): +def deposit_gas(shell: Shell, amount: int, wallet_from_path: str, wallet_from_password: str): """ Transferring GAS from given wallet to NeoFS contract address. """ # get NeoFS contract address - deposit_addr = converters.contract_hash_to_address(NEOFS_CONTRACT) + deposit_addr = contract_hash_to_address(NEOFS_CONTRACT) logger.info(f"NeoFS contract address: {deposit_addr}") - - address_to = _address_from_wallet(wallet_to, wallet_password) - - txid = nep17_transfer( - wallet_to, - deposit_addr, - amount, - NEO_MAINNET_ENDPOINT, - wallet_pass=wallet_password, - addr_from=address_to, + address_from = get_last_address_from_wallet( + wallet_path=wallet_from_path, wallet_password=wallet_from_password + ) + transfer_gas( + shell=shell, + amount=amount, + wallet_from_path=wallet_from_path, + wallet_from_password=wallet_from_password, + address_to=deposit_addr, + address_from=address_from, ) - if not transaction_accepted(txid): - raise AssertionError(f"TX {txid} hasn't been processed") - - -def _address_from_wallet(wlt: str, wallet_password: str): - """ - Extracting the address from the given wallet. - Args: - wlt (str): the path to the wallet to extract address from - wallet_password (str): the password for the given wallet - Returns: - (str): the address for the wallet - """ - wallet_loaded = load_wallet(wlt, wallet_password) - address = wallet_loaded.accounts[-1].address - logger.info(f"got address: {address}") - return address @allure.step("Get Mainnet Balance") def get_mainnet_balance(address: str): - resp = mainnet_rpc_cli.get_nep17_balances(address=address) + resp = mainnet_rpc_client.get_nep17_balances(address=address) logger.info(f"Got getnep17balances response: {resp}") for balance in resp["balance"]: if balance["assethash"] == GAS_HASH: @@ -183,7 +204,7 @@ def get_mainnet_balance(address: str): @allure.step("Get Sidechain Balance") def get_sidechain_balance(address: str): - resp = morph_rpc_cli.get_nep17_balances(address=address) + resp = morph_rpc_client.get_nep17_balances(address=address) logger.info(f"Got getnep17balances response: {resp}") for balance in resp["balance"]: if balance["assethash"] == GAS_HASH: