diff --git a/robot/resources/lib/gates.py b/robot/resources/lib/gates.py index 7484a93..5400f55 100644 --- a/robot/resources/lib/gates.py +++ b/robot/resources/lib/gates.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python3.8 import logging import os diff --git a/robot/resources/lib/neofs.py b/robot/resources/lib/neofs.py index 417f45d..2019a0b 100644 --- a/robot/resources/lib/neofs.py +++ b/robot/resources/lib/neofs.py @@ -1,20 +1,21 @@ #!/usr/bin/python3.8 -import subprocess +import base58 +import base64 +import binascii +from datetime import datetime +import docker +import hashlib +import json import os import re -import hashlib +import random +import subprocess + +from neo3 import wallet from robot.api.deco import keyword from robot.api import logger -import random -import base64 -import base58 -import docker -import json -import tarfile -import binascii -from datetime import datetime from common import * ROBOT_AUTO_KEYWORDS = False @@ -24,22 +25,9 @@ NEOFS_CLI_EXEC = os.getenv('NEOFS_CLI_EXEC', 'neofs-cli') @keyword('Get ScriptHash') -def get_scripthash(privkey: str): - scripthash = "" - Cmd = f'{NEOFS_CLI_EXEC} util keyer -u {privkey}' - logger.info("Cmd: %s" % Cmd) - complProc = subprocess.run(Cmd, check=True, universal_newlines=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True) - output = complProc.stdout - logger.info("Output: %s" % output) - - m = re.search(r'ScriptHash3.0 (\w+)', output) - if m.start() != m.end(): - scripthash = m.group(1) - else: - raise Exception("Can not get ScriptHash.") - - return scripthash +def get_scripthash(wif: str): + acc = wallet.Account.from_wif(wif, '') + return str(acc.script_hash) @keyword('Stop nodes') @@ -279,7 +267,7 @@ def get_range(private_key: str, cid: str, oid: str, range_file: str, bearer: str raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) @keyword('Create container') -def create_container(private_key: str, basic_acl:str, rule:str, user_headers: str=None): +def create_container(private_key: str, basic_acl:str, rule:str, user_headers: str=''): if rule == "": logger.error("Cannot create container with empty placement rule") @@ -295,7 +283,7 @@ def create_container(private_key: str, basic_acl:str, rule:str, user_headers: st logger.info("Cmd: %s" % createContainerCmd) try: complProc = subprocess.run(createContainerCmd, check=True, universal_newlines=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=300, shell=True) + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=300, shell=True) output = complProc.stdout logger.info("Output: %s" % output) cid = _parse_cid(output) @@ -364,9 +352,11 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s if expected_objects_list: if sorted(found_objects) == sorted(expected_objects_list): - logger.info("Found objects list '{}' is equal for expected list '{}'".format(found_objects, expected_objects_list)) + logger.info(f"Found objects list '{found_objects}' ", + f"is equal for expected list '{expected_objects_list}'") else: - raise Exception("Found object list '{}' is not equal to expected list '{}'".format(found_objects, expected_objects_list)) + raise Exception(f"Found object list {found_objects} ", + f"is not equal to expected list '{expected_objects_list}'") return found_objects @@ -550,7 +540,7 @@ def _get_raw_split_information(header): result_header['Type'] = m.group(1) else: raise Exception("no Type was parsed from object header: \t%s" % header) - + # PayloadLength m = re.search(r'Size: (\d+)', header) if m is not None: @@ -581,7 +571,7 @@ def _get_raw_split_information(header): result_header['Split ChildID'] = found_objects logger.info("Result: %s" % result_header) - return result_header + return result_header @keyword('Verify Head Tombstone') def verify_head_tombstone(private_key: str, cid: str, oid_ts: str, oid: str, addr: str): @@ -755,7 +745,7 @@ def decode_object_system_header_json(header): result_header["PayloadLength"] = PayloadLength else: raise Exception("no PayloadLength was parsed from header: \t%s" % header) - + # HomoHash HomoHash = json_header["header"]["homomorphicHash"]["sum"] @@ -770,14 +760,14 @@ def decode_object_system_header_json(header): Checksum_64_d = base64.b64decode(Checksum) result_header["Checksum"] = binascii.hexlify(Checksum_64_d) else: - raise Exception("no Checksum was parsed from header: \t%s" % header) + raise Exception("no Checksum was parsed from header: \t%s" % header) # Type Type = json_header["header"]["objectType"] if Type is not None: result_header["Type"] = Type else: - raise Exception("no Type was parsed from header: \t%s" % header) + raise Exception("no Type was parsed from header: \t%s" % header) # Header - Optional attributes diff --git a/robot/resources/lib/payment_neogo.py b/robot/resources/lib/payment_neogo.py index 9657196..533160e 100644 --- a/robot/resources/lib/payment_neogo.py +++ b/robot/resources/lib/payment_neogo.py @@ -1,24 +1,24 @@ #!/usr/bin/python3 -import subprocess +import os import pexpect import re -import uuid -import requests -import json -import os from robot.api.deco import keyword from robot.api import logger -import robot.errors -from robot.libraries.BuiltIn import BuiltIn +from neo3 import wallet from common import * +import rpc_client ROBOT_AUTO_KEYWORDS = False # path to neofs-cli executable -NEOFS_CLI_EXEC = os.getenv('NEOFS_CLI_EXEC', 'neofs-cli') +BALANCE_CONTRACT_HASH = os.getenv('NEOFS_CONTRACTS_BALANCE') +MORPH_TOKEN_POWER = 12 + +morph_rpc_cli = rpc_client.RPCClient(NEOFS_NEO_API_ENDPOINT) +mainnet_rpc_cli = rpc_client.RPCClient(NEO_MAINNET_ENDPOINT) @keyword('Withdraw Mainnet Gas') @@ -40,65 +40,47 @@ def withdraw_mainnet_gas(wallet: str, address: str, scripthash: str, amount: int @keyword('Transaction accepted in block') -def transaction_accepted_in_block(tx_id): +def transaction_accepted_in_block(tx_id: str): """ This function return True in case of accepted TX. Parameters: - :param tx_id: transaction is - :rtype: block number or Exception + :param tx_id: transaction ID """ - logger.info("Transaction id: %s" % tx_id) - - headers = {'Content-type': 'application/json'} - data = { "jsonrpc": "2.0", "id": 5, "method": "gettransactionheight", "params": [ tx_id ] } - response = requests.post(NEO_MAINNET_ENDPOINT, json=data, headers=headers, verify=False) - - if not response.ok: - raise Exception(f"""Failed: - request: {data}, - response: {response.text}, - status code: {response.status_code} {response.reason}""") - - if (response.text == 0): - raise Exception( "Transaction is not found in the blocks." ) - - logger.info("Transaction has been found in the block %s." % response.text ) - return response.text + try: + resp = mainnet_rpc_cli.get_transaction_height(tx_id) + if resp is not None: + logger.info(f"got block height: {resp}") + return True + except Exception as e: + logger.info(f"request failed with error: {e}") + raise e @keyword('Get NeoFS Balance') -def get_balance(privkey: str): +def get_balance(wif: str): """ - This function returns NeoFS balance for selected public key. - :param public_key: neo public key + This function returns NeoFS balance for given WIF. """ - balance = _get_balance_request(privkey) + acc = wallet.Account.from_wif(wif, '') + payload = [ + { + 'type': 'Hash160', + 'value': str(acc.script_hash) + } + ] + try: + resp = morph_rpc_cli.invoke_function( + BALANCE_CONTRACT_HASH, 'balanceOf', payload + ) + logger.info(resp) + value = int(resp['stack'][0]['value']) + return value/(10**MORPH_TOKEN_POWER) + except Exception as e: + logger.error(f"failed to get {wif} balance: {e}") + raise e - return float(balance) - - -def _get_balance_request(privkey: str): - ''' - Internal method. - ''' - Cmd = ( - f'{NEOFS_CLI_EXEC} --wif {privkey} --rpc-endpoint {NEOFS_ENDPOINT}' - f' accounting balance' - ) - logger.info(f"Cmd: {Cmd}") - complProc = subprocess.run(Cmd, check=True, universal_newlines=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True) - output = complProc.stdout - logger.info(f"Output: {output}") - - if output is None: - BuiltIn().fatal_error(f'Can not parse balance: "{output}"') - - logger.info(f"Balance for '{privkey}' is '{output}'" ) - - return output def _run_sh_with_passwd(passwd, cmd): p = pexpect.spawn(cmd) diff --git a/robot/resources/lib/payment_operations.robot b/robot/resources/lib/payment_operations.robot index e6c5b3d..752c0da 100644 --- a/robot/resources/lib/payment_operations.robot +++ b/robot/resources/lib/payment_operations.robot @@ -41,5 +41,5 @@ Payment Operations # For certainty, sleeping during one morph block. Sleep ${MORPH_BLOCK_TIME} - ${NEOFS_BALANCE} = Get NeoFS Balance ${WIF} - Should Be Equal As Numbers ${NEOFS_BALANCE} ${DEPOSIT_AMOUNT} + ${NEOFS_BALANCE} = Get NeoFS Balance ${WIF} + Should Be Equal As Numbers ${NEOFS_BALANCE} ${DEPOSIT_AMOUNT} diff --git a/robot/resources/lib/utility_keywords.py b/robot/resources/lib/utility_keywords.py index f53eda2..865fd8f 100644 --- a/robot/resources/lib/utility_keywords.py +++ b/robot/resources/lib/utility_keywords.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3.7 +#!/usr/bin/python3.8 import docker import os diff --git a/robot/testsuites/integration/network/netmap_simple.robot b/robot/testsuites/integration/network/netmap_simple.robot index f3deafd..0634328 100644 --- a/robot/testsuites/integration/network/netmap_simple.robot +++ b/robot/testsuites/integration/network/netmap_simple.robot @@ -85,10 +85,10 @@ Generate Key and Pre-payment Validate Policy [Arguments] ${POLICY} ${EXPECTED_VAL} @{EXPECTED_LIST} - Log Container with rule ${POLICY} + Log Container with rule ${POLICY} - ${CID} = Create container ${PRIV_KEY} ${EMPTY} ${POLICY} - Container Existing ${PRIV_KEY} ${CID} + ${CID} = Create container ${PRIV_KEY} ${EMPTY} ${POLICY} + Container Existing ${PRIV_KEY} ${CID} ${S_OID} = Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${EMPTY} - Validate storage policy for object ${PRIV_KEY} ${EXPECTED_VAL} ${CID} ${S_OID} @{EXPECTED_LIST} + Validate storage policy for object ${PRIV_KEY} ${EXPECTED_VAL} ${CID} ${S_OID} ${EXPECTED_LIST} Get object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read diff --git a/robot/testsuites/integration/object/object_simple.robot b/robot/testsuites/integration/object/object_simple.robot index bfdb9b0..7a24550 100644 --- a/robot/testsuites/integration/object/object_simple.robot +++ b/robot/testsuites/integration/object/object_simple.robot @@ -3,6 +3,7 @@ Variables ../../../variables/common.py Library ../${RESOURCES}/neofs.py Library ../${RESOURCES}/payment_neogo.py +Library ${KEYWORDS}/contract_keywords.py Resource common_steps_object.robot Resource ../${RESOURCES}/payment_operations.robot diff --git a/robot/variables/common.py b/robot/variables/common.py index faf1c26..7691aad 100644 --- a/robot/variables/common.py +++ b/robot/variables/common.py @@ -16,7 +16,7 @@ ABSOLUTE_FILE_PATH="/robot/testsuites/integration" NEOFS_EPOCH_TIMEOUT = (os.getenv("NEOFS_EPOCH_TIMEOUT") if os.getenv("NEOFS_EPOCH_TIMEOUT") else os.getenv("NEOFS_IR_TIMERS_EPOCH", "300s")) -SIMPLE_OBJ_SIZE = os.getenv("SIMPLE_OBJ_SIZE", "1024") +SIMPLE_OBJ_SIZE = os.getenv("SIMPLE_OBJ_SIZE", "1000") COMPLEX_OBJ_SIZE = os.getenv("COMPLEX_OBJ_SIZE", "70000000") MAINNET_BLOCK_TIME = os.getenv('MAINNET_BLOCK_TIME', "15s") diff --git a/wallets/selectel_mainnet_wallet.json b/wallets/selectel_mainnet_wallet.json deleted file mode 100644 index 1612925..0000000 --- a/wallets/selectel_mainnet_wallet.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "version": "3.0", - "accounts": [ - { - "address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc", - "key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux", - "label": "", - "contract": { - "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=", - "parameters": [ - { - "name": "parameter0", - "type": "Signature" - } - ], - "deployed": false - }, - "lock": false, - "isdefault": false - }, - { - "address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY", - "key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux", - "label": "", - "contract": { - "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==", - "parameters": [ - { - "name": "parameter0", - "type": "Signature" - }, - { - "name": "parameter1", - "type": "Signature" - }, - { - "name": "parameter2", - "type": "Signature" - } - ], - "deployed": false - }, - "lock": false, - "isdefault": false - }, - { - "address": "NVNvVRW5Q5naSx2k2iZm7xRgtRNGuZppAK", - "key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux", - "label": "", - "contract": { - "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEQtBE43vrw==", - "parameters": [ - { - "name": "parameter0", - "type": "Signature" - } - ], - "deployed": false - }, - "lock": false, - "isdefault": false - } - ], - "scrypt": { - "n": 16384, - "r": 8, - "p": 8 - }, - "extra": { - "Tokens": null - } -}