From 0c4a035e22d1b94d16e3a41285b7f48f516412c7 Mon Sep 17 00:00:00 2001 From: anastasia prasolova Date: Mon, 30 Nov 2020 13:33:05 +0300 Subject: [PATCH 1/2] INFRA-236 selectel cdn smoke tests --- robot/resources/lib/gates.py | 41 ++++++ robot/resources/lib/neofs.py | 94 ++++++------- robot/resources/lib/neofs_int_vars.py | 9 ++ robot/resources/lib/payment_neogo.py | 125 ++++-------------- robot/resources/lib/selectelcdn_smoke_vars.py | 9 ++ .../testsuites/smoke/selectelcdn_smoke.robot | 33 +++++ robot/variables/common.py | 10 +- robot/variables/selectelcdn_smoke.py | 8 ++ wallets/selectel_mainnet_wallet.json | 72 ++++++++++ 9 files changed, 253 insertions(+), 148 deletions(-) create mode 100644 robot/resources/lib/gates.py create mode 100644 robot/resources/lib/neofs_int_vars.py create mode 100644 robot/resources/lib/selectelcdn_smoke_vars.py create mode 100644 robot/testsuites/smoke/selectelcdn_smoke.robot create mode 100644 robot/variables/selectelcdn_smoke.py create mode 100644 wallets/selectel_mainnet_wallet.json diff --git a/robot/resources/lib/gates.py b/robot/resources/lib/gates.py new file mode 100644 index 00000000..d33b9ddf --- /dev/null +++ b/robot/resources/lib/gates.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 + +import logging +import os +import requests + +from robot.api.deco import keyword +from robot.api import logger +import robot.errors +from robot.libraries.BuiltIn import BuiltIn + + +ROBOT_AUTO_KEYWORDS = False + +if os.getenv('ROBOT_PROFILE') == 'selectel_smoke': + from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT, + NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT, HTTP_GATE) +else: + from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT, + NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT, HTTP_GATE) + + +@keyword('Get via HTTP Gate') +def get_via_http_gate(cid: str, oid: str): + """ + This function gets given object from HTTP gate + :param cid: CID to get object from + :param oid: object OID + """ + resp = requests.get(f'{HTTP_GATE}/get/{cid}/{oid}') + if not resp.ok: + logger.info(f"""Failed to get object via HTTP gate: + request: {resp.request.path_url}, + response: {resp.text}, + status code: {resp.status_code} {resp.reason}""") + return + + filename = os.path.curdir + f"/{cid}_{oid}" + with open(filename, "w+") as f: + f.write(resp.text) + return filename diff --git a/robot/resources/lib/neofs.py b/robot/resources/lib/neofs.py index 3e7089ed..3645ebf8 100644 --- a/robot/resources/lib/neofs.py +++ b/robot/resources/lib/neofs.py @@ -9,10 +9,15 @@ import hashlib from robot.api.deco import keyword from robot.api import logger +if os.getenv('ROBOT_PROFILE') == 'selectel_smoke': + from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT, + NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT) +else: + from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT, + NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT) ROBOT_AUTO_KEYWORDS = False -NEOFS_ENDPOINT = "s01.neofs.devenv:8080" CLI_PREFIX = "" @keyword('Form WIF from String') @@ -26,7 +31,7 @@ def form_wif_from_string(private_key: str): logger.info("Output: %s" % output) m = re.search(r'WIF\s+(\w+)', output) - if m.start() != m.end(): + if m.start() != m.end(): wif = m.group(1) else: raise Exception("Can not get WIF.") @@ -46,7 +51,7 @@ def get_scripthash(privkey: str): # ScriptHash3.0 00284fc88f8ac31f8e56c03301bfab0757e3f212 m = re.search(r'ScriptHash3.0 (\w+)', output) - if m.start() != m.end(): + if m.start() != m.end(): scripthash = m.group(1) else: raise Exception("Can not get ScriptHash.") @@ -141,7 +146,7 @@ def conver_str_to_hex(string_convert: str): @keyword('Set custom eACL') def set_custom_eacl(private_key: bytes, cid: str, eacl_prefix: str, eacl_slice: str, eacl_postfix: str): - + logger.info(str(eacl_prefix)) logger.info(str(eacl_slice)) logger.info(str(eacl_postfix)) @@ -170,9 +175,9 @@ def set_eacl(private_key: bytes, cid: str, eacl: str): def get_range(private_key: str, cid: str, oid: str, bearer: str, range_cut: str): bearer_token = "" - if bearer: + if bearer: bearer_token = f"--bearer {bearer}" - + Cmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object get-range --cid {cid} --oid {oid} {bearer_token} {range_cut} ' logger.info("Cmd: %s" % Cmd) complProc = subprocess.run(Cmd, check=True, universal_newlines=True, @@ -183,10 +188,10 @@ def get_range(private_key: str, cid: str, oid: str, bearer: str, range_cut: str) @keyword('Create container') def create_container(private_key: str, basic_acl:str="", rule:str="REP 2 IN X CBF 1 SELECT 2 FROM * AS X"): - + if basic_acl != "": basic_acl = "--basic-acl " + basic_acl - + createContainerCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} container create --policy "{rule}" {basic_acl} --await' logger.info("Cmd: %s" % createContainerCmd) complProc = subprocess.run(createContainerCmd, check=True, universal_newlines=True, @@ -210,7 +215,7 @@ def container_existing(private_key: str, cid: str): complProc = subprocess.run(Cmd, check=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True) logger.info("Output: %s" % complProc.stdout) - + _find_cid(complProc.stdout, cid) return @@ -230,14 +235,14 @@ def generate_file_of_bytes(size): fout.write(os.urandom(size)) logger.info("Random binary file with size %s bytes has been generated." % str(size)) - return filename + return os.path.abspath(os.getcwd()) + '/' + filename @keyword('Search object') def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: str, *expected_objects_list ): bearer_token = "" - if bearer: + if bearer: bearer_token = f"--bearer {bearer}" @@ -255,7 +260,7 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s if expected_objects_list: found_objects = re.findall(r'(\w{43,44})', complProc.stdout) - + if sorted(found_objects) == sorted(expected_objects_list): logger.info("Found objects list '{}' is equal for expected list '{}'".format(found_objects, expected_objects_list)) else: @@ -264,7 +269,7 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s except subprocess.CalledProcessError as e: - raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) + raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) @keyword('Verify Head Tombstone') @@ -281,7 +286,7 @@ def verify_head_tombstone(private_key: str, cid: str, oid: str): logger.info("Tombstone header 'Type=Tombstone Value=MARKED' was parsed from command output") else: raise Exception("Tombstone header 'Type=Tombstone Value=MARKED' was not found in the command output: \t%s" % (complProc.stdout)) - + except subprocess.CalledProcessError as e: raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) @@ -300,20 +305,20 @@ def _exec_cli_cmd(private_key: bytes, postfix: str): except subprocess.CalledProcessError as e: raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) - + return complProc.stdout @keyword('Verify linked objects') def verify_linked_objects(private_key: bytes, cid: str, oid: str, payload_size: float): - + payload_size = int(float(payload_size)) # Get linked objects from first postfix = f'object head --cid {cid} --oid {oid} --full-headers' output = _exec_cli_cmd(private_key, postfix) child_obj_list = [] - + for m in re.finditer(r'Type=Child ID=([\w-]+)', output): child_obj_list.append(m.group(1)) @@ -324,7 +329,7 @@ def verify_linked_objects(private_key: bytes, cid: str, oid: str, payload_size: raise Exception("Child objects was not found.") else: logger.info("Child objects: %s" % child_obj_list) - + # HEAD and validate each child object: payload = 0 parent_id = "00000000-0000-0000-0000-000000000000" @@ -342,7 +347,7 @@ def verify_linked_objects(private_key: bytes, cid: str, oid: str, payload_size: if not first_obj: raise Exception("Can not find first object with zero Parent ID.") else: - + _check_linked_object(first_obj, child_obj_list_headers, payload_size, payload, parent_id) return child_obj_list_headers.keys() @@ -358,11 +363,11 @@ def _check_linked_object(obj:str, child_obj_list_headers:dict, payload_size:int, logger.info("Previous ID is equal for expected: %s" % parent_id) m = re.search(r'PayloadLength=(\d+)', output) - if m.start() != m.end(): + if m.start() != m.end(): payload += int(m.group(1)) else: raise Exception("Can not get payload for the object %s." % obj) - + if payload > payload_size: raise Exception("Payload exceeds expected total payload %s." % payload_size) @@ -371,10 +376,10 @@ def _check_linked_object(obj:str, child_obj_list_headers:dict, payload_size:int, raise Exception("Incorrect previos ID in the last child object %s." % obj) else: logger.info("Next ID is correct for the final child object: %s" % obj) - + else: m = re.search(r'Type=Next ID=([\w-]+)', output) - if m: + if m: # next object should be in the expected list logger.info(m.group(1)) if m.group(1) not in child_obj_list_headers.keys(): @@ -409,13 +414,13 @@ def head_object(private_key: str, cid: str, oid: str, bearer: str, user_headers: logger.info("User header %s was parsed from command output" % key) else: raise Exception("User header %s was not found in the command output: \t%s" % (key, complProc.stdout)) - + return complProc.stdout except subprocess.CalledProcessError as e: raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) - + @keyword('Parse Object System Header') @@ -444,7 +449,7 @@ def parse_object_system_header(header: str): result_header['OwnerID'] = m.group(1) else: raise Exception("no OwnerID was parsed from object header: \t%s" % output) - + # Version m = re.search(r'- Version=(\d+)', header) if m.start() != m.end(): # e.g., if match found something @@ -461,7 +466,7 @@ def parse_object_system_header(header: str): raise Exception("no PayloadLength was parsed from object header: \t%s" % output) - + # CreatedAtUnixTime m = re.search(r'- CreatedAt={UnixTime=(\d+)', header) if m.start() != m.end(): # e.g., if match found something @@ -479,26 +484,26 @@ def parse_object_system_header(header: str): logger.info("Result: %s" % result_header) return result_header - + @keyword('Parse Object Extended Header') def parse_object_extended_header(header: str): result_header = dict() - + pattern = re.compile(r'- Type=(\w+)\n.+Value=(.+)\n') - + for (f_type, f_val) in re.findall(pattern, header): logger.info("found: %s - %s" % (f_type, f_val)) if f_type not in result_header.keys(): result_header[f_type] = [] - + result_header[f_type].append(f_val) logger.info("Result: %s" % result_header) return result_header - + @keyword('Delete object') def delete_object(private_key: str, cid: str, oid: str, bearer: str): @@ -513,7 +518,7 @@ def delete_object(private_key: str, cid: str, oid: str, bearer: str): stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True) logger.info("Output: %s" % complProc.stdout) except subprocess.CalledProcessError as e: - raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) + raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) @keyword('Get file hash') @@ -556,7 +561,7 @@ def get_storage_group(private_key: bytes, cid: str, sgid: str): logger.info("Output: %s" % complProc.stdout) except subprocess.CalledProcessError as e: raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) - + @keyword('Cleanup File') # remove temp files @@ -564,11 +569,11 @@ def cleanup_file(filename: str): if os.path.isfile(filename): try: os.remove(filename) - except OSError as e: + except OSError as e: raise Exception("Error: '%s' - %s." % (e.filename, e.strerror)) - else: + else: raise Exception("Error: '%s' file not found" % filename) - + logger.info("File '%s' has been deleted." % filename) @@ -593,10 +598,10 @@ def put_object(private_key: str, path: str, cid: str, bearer: str, user_headers: @keyword('Get Range Hash') def get_range_hash(private_key: str, cid: str, oid: str, bearer_token: str, range_cut: str): - - if bearer_token: + + if bearer_token: bearer_token = f"--bearer {bearer}" - + ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object hash --cid {cid} --oid {oid} --range {range_cut} {bearer_token}' logger.info("Cmd: %s" % ObjectCmd) @@ -607,7 +612,6 @@ def get_range_hash(private_key: str, cid: str, oid: str, bearer_token: str, rang except subprocess.CalledProcessError as e: raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) - @keyword('Get object from NeoFS') def get_object(private_key: str, cid: str, oid: str, bearer_token: str, read_object: str): @@ -659,7 +663,7 @@ def _parse_oid(output: str): oid = m.group(1) else: raise Exception("no OID was parsed from command output: \t%s" % output) - + return oid def _parse_cid(output: str): @@ -672,7 +676,7 @@ def _parse_cid(output: str): if not m.start() != m.end(): # e.g., if match found something raise Exception("no CID was parsed from command output: \t%s" % (output)) cid = m.group(1) - + return cid def _get_storage_nodes(private_key: bytes): @@ -684,7 +688,7 @@ def _get_storage_nodes(private_key: bytes): #logger.info("Netmap: %s" % output) #for m in re.finditer(r'"address":"/ip4/(\d+\.\d+\.\d+\.\d+)/tcp/(\d+)"', output): # storage_nodes.append(m.group(1)+":"+m.group(2)) - + #if not storage_nodes: # raise Exception("Storage nodes was not found.") @@ -718,4 +722,4 @@ def _search_object(node:str, private_key: str, cid:str, oid: str): raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) - \ No newline at end of file + diff --git a/robot/resources/lib/neofs_int_vars.py b/robot/resources/lib/neofs_int_vars.py new file mode 100644 index 00000000..7e2ea29d --- /dev/null +++ b/robot/resources/lib/neofs_int_vars.py @@ -0,0 +1,9 @@ +#!/usr/bin/python3 +import os + +NEOFS_ENDPOINT = "s01.neofs.devenv:8080" +NEOGO_CLI_PREFIX = "docker exec -it main_chain neo-go" +NEO_MAINNET_ENDPOINT = "main_chain.neofs.devenv:30333" + +NEOFS_NEO_API_ENDPOINT = 'http://main_chain.neofs.devenv:30333' +HTTP_GATE = '' diff --git a/robot/resources/lib/payment_neogo.py b/robot/resources/lib/payment_neogo.py index fe3ac42f..3a10f0b7 100644 --- a/robot/resources/lib/payment_neogo.py +++ b/robot/resources/lib/payment_neogo.py @@ -4,15 +4,14 @@ import subprocess import pexpect import re import uuid +import logging +import requests +import json +import os from robot.api.deco import keyword from robot.api import logger - -import logging import robot.errors -import requests -import json - from robot.libraries.BuiltIn import BuiltIn from neocore.KeyPair import KeyPair @@ -20,11 +19,15 @@ from Crypto import Random ROBOT_AUTO_KEYWORDS = False +if os.getenv('ROBOT_PROFILE') == 'selectel_smoke': + from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT, + NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT) +else: + from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT, + NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT) NEOFS_CONTRACT = "5f490fbd8010fd716754073ee960067d28549b7d" -NEOGO_CLI_PREFIX = "docker exec -it main_chain neo-go" -NEO_MAINNET_ENDPOINT = "main_chain.neofs.devenv:30333" @keyword('Init wallet') def init_wallet(): @@ -33,7 +36,7 @@ def init_wallet(): cmd = ( f"{NEOGO_CLI_PREFIX} wallet init -w {filename}" ) logger.info(f"Executing shell command: {cmd}") - out = run_sh(cmd) + out = run_sh(cmd) logger.info(f"Command completed with output: {out}") return filename @@ -59,11 +62,11 @@ def dump_address(wallet: str): cmd = ( f"{NEOGO_CLI_PREFIX} wallet dump -w {wallet}" ) logger.info(f"Executing command: {cmd}") - out = run_sh(cmd) + out = run_sh(cmd) logger.info(f"Command completed with output: {out}") m = re.search(r'"address": "(\w+)"', out) - if m.start() != m.end(): + if m.start() != m.end(): address = m.group(1) else: raise Exception("Can not get address.") @@ -80,10 +83,7 @@ def dump_privkey(wallet: str, address: str): return out - -@keyword('Transfer Mainnet Gas') -# docker cp wallets/wallet.json main_chain:/wallets/ - +@keyword('Transfer Mainnet Gas') def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int): cmd = ( f"{NEOGO_CLI_PREFIX} wallet nep5 transfer -w {wallet} -r http://main_chain.neofs.devenv:30333 --from {address} " f"--to {address_to} --token gas --amount {amount}" ) @@ -97,9 +97,7 @@ def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int return out -@keyword('Withdraw Mainnet Gas') -# docker cp wallets/wallet.json main_chain:/wallets/ - +@keyword('Withdraw Mainnet Gas') def withdraw_mainnet_gas(wallet: str, address: str, scripthash: str, amount: int): cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} -r http://main_chain.neofs.devenv:30333 " f"{NEOFS_CONTRACT} withdraw {scripthash} int:{amount} -- {scripthash}" ) @@ -113,10 +111,6 @@ def withdraw_mainnet_gas(wallet: str, address: str, scripthash: str, amount: int return out -# neo-go contract invokefunction -w wallets/deploy_wallet.json -a NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx -r http://main_chain.neofs.devenv:30333 -# 5f490fbd8010fd716754073ee960067d28549b7d withdraw 12b97a2206ae4b10c7e0194b7b655c32cc912057 int:10 -- 12b97a2206ae4b10c7e0194b7b655c32cc912057 - - @keyword('Mainnet Balance') def mainnet_balance(address: str): request = 'curl -X POST '+NEO_MAINNET_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "getnep5balances", "params": [\"'+address+'\"] }\'' @@ -129,37 +123,31 @@ def mainnet_balance(address: str): logger.info(out) m = re.search(r'"668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","amount":"([\d\.]+)"', out) - if not m.start() != m.end(): + if not m.start() != m.end(): raise Exception("Can not get mainnet gas balance.") amount = m.group(1) - + return amount @keyword('Expexted Mainnet Balance') def expected_mainnet_balance(address: str, expected: int): - + amount = mainnet_balance(address) if float(amount) != float(expected): raise Exception(f"Expected amount ({expected}) of GAS has not been found. Found {amount}.") return True -# balance":[{"assethash":"668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","amount":"50" -#curl -d '{ "jsonrpc": "2.0", "id": 1, "method": "getnep5balances", "params": ["NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx"] }' main_chain.neofs.devenv:30333 -#{"id":1,"jsonrpc":"2.0","result":{"balance":[{"assethash":"668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","amount":"9237.47595500","lastupdatedblock":158}],"address":"NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx"}} - - - -@keyword('NeoFS Deposit') -def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int): +@keyword('NeoFS Deposit') +def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int, wallet_pass:str=''): cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} " - f"-r http://main_chain.neofs.devenv:30333 {NEOFS_CONTRACT} " + f"-r {NEOFS_NEO_API_ENDPOINT} {NEOFS_CONTRACT} " f"deposit {scripthash} int:{amount} bytes: -- {scripthash}") logger.info(f"Executing command: {cmd}") - out = run_sh_with_passwd('', cmd) + out = run_sh_with_passwd(wallet_pass, cmd) logger.info(f"Command completed with output: {out}") m = re.match(r'^Sent invocation transaction (\w{64})$', out) @@ -172,32 +160,6 @@ def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int): return tx - #docker exec -it main_chain \ - # neo-go contract invokefunction \ - # -w wallets/wallet.json \ - # -a NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx \ - # -r http://main_chain.${LOCAL_DOMAIN}:30333 \ - # ${NEOFS_CONTRACT_MAINCHAIN} \ - # deposit \ - # 12b97a2206ae4b10c7e0194b7b655c32cc912057 \ - # int:500 \ - # bytes: \ - # -- 12b97a2206ae4b10c7e0194b7b655c32cc912057 - -#neo-go contract invokefunction -w wallets/wallet.json -a NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx -#-r af5dc5f7e6a6efc64d679098f328027591a2e518 -#deposit 12b97a2206ae4b10c7e0194b7b655c32cc912057 int:60 bytes: -- -#12b97a2206ae4b10c7e0194b7b655c32cc912057 - - - - - -# wallet nep5 transfer -w wallets/wallet.json -r http://main_chain.neofs.devenv:30333 --from NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx -# --to NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt --token gas --amount 50 - - - @keyword('Transaction accepted in block') def transaction_accepted_in_block(tx_id): """ @@ -208,14 +170,10 @@ def transaction_accepted_in_block(tx_id): """ logger.info("Transaction id: %s" % tx_id) - - -# curl -d '{ "jsonrpc": "2.0", "id": 1, "method": "getnep5transfers", "params": ["NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt"] }' main_chain.neofs.devenv:30333 TX_request = 'curl -X POST '+NEO_MAINNET_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "gettransactionheight", "params": [\"'+ tx_id +'\"] }\'' - + logger.info(f"Executing command: {TX_request}") - complProc = subprocess.run(TX_request, check=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True) @@ -227,7 +185,6 @@ def transaction_accepted_in_block(tx_id): logger.info("Transaction has been found in the block %s." % response['result'] ) return response['result'] - @keyword('Get Transaction') def get_transaction(tx_id: str): @@ -241,15 +198,6 @@ def get_transaction(tx_id: str): complProc = subprocess.run(TX_request, check=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True) logger.info(complProc.stdout) - - - - - - - - - def run_sh(args): complProc = subprocess.run(args, check=True, universal_newlines=True, @@ -301,13 +249,6 @@ def run_sh_with_passwd(passwd, cmd): logger.info("Output: %s" % output) - -#from subprocess import Popen, PIPE -#p = Popen(['python test_enter.py'], stdin=PIPE, shell=True) -#p.communicate(input='\n') - - - @keyword('Request NeoFS Deposit') def request_neofs_deposit(public_key: str): """ @@ -315,8 +256,8 @@ def request_neofs_deposit(public_key: str): :param public_key: neo public key """ - response = requests.get('https://fs.localtest.nspcc.ru/api/deposit/'+str(public_key), verify='ca/nspcc-ca.pem') - + response = requests.get('https://fs.localtest.nspcc.ru/api/deposit/'+str(public_key), verify='ca/nspcc-ca.pem') + if response.status_code != 200: BuiltIn().fatal_error('Can not run Deposit to {} with error: {}'.format(public_key, response.text)) else: @@ -354,19 +295,18 @@ def expected_balance(privkey: str, init_amount: float, deposit_size: float): return deposit_change - def _get_balance_request(privkey: str): ''' Internal method. ''' - Cmd = f'neofs-cli --key {privkey} --rpc-endpoint s01.neofs.devenv:8080 accounting balance' + Cmd = f'neofs-cli --key {privkey} --rpc-endpoint {NEOFS_ENDPOINT} accounting balance' 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.match(r'(-?[\d.\.?\d*]+)', output ) if m is None: BuiltIn().fatal_error('Can not parse balance: "%s"' % output) @@ -375,12 +315,3 @@ def _get_balance_request(privkey: str): logger.info("Balance for '%s' is '%s'" % (privkey, balance) ) return balance - - - - - # {"id":5,"jsonrpc":"2.0","result":{"txid":"0x02c178803258a9dbbcce80acfece2f6abb4f51c122e7ce2ddcad332d6a810e5f","trigger":"Application", - # !!!!!!!!!!! - #"vmstate":"FAULT" - # !!!!!!!!!!! - #,"gasconsumed":"11328110","stack":[],"notifications":[]}} \ No newline at end of file diff --git a/robot/resources/lib/selectelcdn_smoke_vars.py b/robot/resources/lib/selectelcdn_smoke_vars.py new file mode 100644 index 00000000..d9ad407b --- /dev/null +++ b/robot/resources/lib/selectelcdn_smoke_vars.py @@ -0,0 +1,9 @@ +#!/usr/bin/python3 + +NEOFS_ENDPOINT = "92.53.71.51:18080" +NEOGO_CLI_PREFIX = "neo-go" +NEO_MAINNET_ENDPOINT = "http://92.53.71.51:20332" + +# selectel main chain on lobachevsky-1 +NEOFS_NEO_API_ENDPOINT = "http://92.53.71.51:20332" +HTTP_GATE = 'http://92.53.71.51:38080' diff --git a/robot/testsuites/smoke/selectelcdn_smoke.robot b/robot/testsuites/smoke/selectelcdn_smoke.robot new file mode 100644 index 00000000..56424862 --- /dev/null +++ b/robot/testsuites/smoke/selectelcdn_smoke.robot @@ -0,0 +1,33 @@ +# -*- coding: robot -*- + +*** Settings *** +Variables ../../variables/common.py +Variables ../../variables/selectelcdn_smoke.py + + +Library ${RESOURCES}/neofs.py +Library ${RESOURCES}/payment_neogo.py +Library ${RESOURCES}/gates.py + + +*** Test cases *** + +NeoFS Storage Smoke + [Documentation] Creates container and does PUT, GET and LIST on it via CLI and via HTTP Gate + [Timeout] 5 min + + + ${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 50 one + Wait Until Keyword Succeeds 1 min 15 sec + ... Transaction accepted in block ${TX_DEPOSIT} + Get Transaction ${TX_DEPOSIT} + + ${CID} = Create container ${PRIV_KEY} public + Wait Until Keyword Succeeds 2 min 30 sec + ... Container Existing ${PRIV_KEY} ${CID} + + ${FILE} = Generate file of bytes 1024 + ${S_OID} = Put object to NeoFS ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${EMPTY} + Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read + + ${FILEPATH} = Get via HTTP Gate ${CID} ${S_OID} diff --git a/robot/variables/common.py b/robot/variables/common.py index 0baa11f7..ee30c5d1 100644 --- a/robot/variables/common.py +++ b/robot/variables/common.py @@ -9,11 +9,9 @@ CERT="%s/../../ca" % ROOT # in case when test is run from root in docker ABSOLUTE_FILE_PATH="/robot/testsuites/integration" -JF_TOKEN = os.getenv('JF_TOKEN') -REG_USR = os.getenv('REG_USR') -REG_PWD = os.getenv('REG_PWD') -NEOFS_ENDPOINT = "s01.fs.localtest.nspcc.ru:8080" -NEOFS_NEO_API_ENDPOINT = "https://fs.localtest.nspcc.ru/neo_rpc/" +JF_TOKEN = os.getenv('JF_TOKEN') +REG_USR = os.getenv('REG_USR') +REG_PWD = os.getenv('REG_PWD') MORPH_BLOCK_TIMEOUT = "10sec" -NEOFS_EPOCH_TIMEOUT = "30sec" \ No newline at end of file +NEOFS_EPOCH_TIMEOUT = "30sec" diff --git a/robot/variables/selectelcdn_smoke.py b/robot/variables/selectelcdn_smoke.py new file mode 100644 index 00000000..279142c6 --- /dev/null +++ b/robot/variables/selectelcdn_smoke.py @@ -0,0 +1,8 @@ +#!/usr/bin/python3 + +# wallet that has assets in selectel mainnet +WALLET = 'wallets/selectel_mainnet_wallet.json' +# address from this wallet anf its representations +ADDR = 'NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc' +SCRIPT_HASH = 'eb88a496178256213f674eb302e44f9d85cf8aaa' +PRIV_KEY = 'KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY' diff --git a/wallets/selectel_mainnet_wallet.json b/wallets/selectel_mainnet_wallet.json new file mode 100644 index 00000000..1612925d --- /dev/null +++ b/wallets/selectel_mainnet_wallet.json @@ -0,0 +1,72 @@ +{ + "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 + } +} From 35554dedd536c0da3102c795403d22f122e46f9f Mon Sep 17 00:00:00 2001 From: anastasia prasolova Date: Mon, 30 Nov 2020 13:53:28 +0300 Subject: [PATCH 2/2] updated readme --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea5566a6..8e599550 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ * object_complex.robot - операции над простым объектом * object_simple.robot - операции над большим объектом * withdraw.robot - оперция Deposit и Withdraw с счета NeoFS - * netmap_simple.robot - проверка Placement policy + * netmap_simple.robot - проверка Placement policy * replication.robot - базовый тесткейс проверки репликации объектов ### Запуск тесткейсов в докере @@ -54,6 +54,21 @@ export BUILD_NEOFS_NODE= ``` +### Запуск smoke-тестов + +Есть сьют со smoke-тестами для CDN-гейтов `robot/testsuites/smoke/selectelcdn_smoke.robot`. +Ему требуются отдельные переменные, в отличие от сьютов NeoFS, которые запускаются на +девэнве. Чтобы библиотеки кейвордов их использовали, нужно установить переменную +окружения +``` +export ROBOT_PROFILE=selectel_smoke +``` +По умолчанию кейворды используют переменные из файла `robot/resources/lib/neofs_int_vars.py`. +``` +robot --outputdir artifacts/ robot/testsuites/smoke/selectelcdn_smoke.robot +``` + + ### Генерация документации Для генерации документации по шагам: @@ -110,4 +125,4 @@ On keywords definition, one should specify variable type, e.g. path: str ### Robot-framework User Guide -http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html \ No newline at end of file +http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html