forked from TrueCloudLab/frostfs-testcases
Few test fixes
Signed-off-by: anastasia prasolova <anastasia@nspcc.ru>
This commit is contained in:
parent
a26118e581
commit
11c4f21faa
9 changed files with 72 additions and 171 deletions
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3.8
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
#!/usr/bin/python3.8
|
#!/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 os
|
||||||
import re
|
import re
|
||||||
import hashlib
|
import random
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from neo3 import wallet
|
||||||
from robot.api.deco import keyword
|
from robot.api.deco import keyword
|
||||||
from robot.api import logger
|
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 *
|
from common import *
|
||||||
|
|
||||||
ROBOT_AUTO_KEYWORDS = False
|
ROBOT_AUTO_KEYWORDS = False
|
||||||
|
@ -24,22 +25,9 @@ NEOFS_CLI_EXEC = os.getenv('NEOFS_CLI_EXEC', 'neofs-cli')
|
||||||
|
|
||||||
|
|
||||||
@keyword('Get ScriptHash')
|
@keyword('Get ScriptHash')
|
||||||
def get_scripthash(privkey: str):
|
def get_scripthash(wif: str):
|
||||||
scripthash = ""
|
acc = wallet.Account.from_wif(wif, '')
|
||||||
Cmd = f'{NEOFS_CLI_EXEC} util keyer -u {privkey}'
|
return str(acc.script_hash)
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
@keyword('Stop nodes')
|
@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))
|
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
|
||||||
|
|
||||||
@keyword('Create container')
|
@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 == "":
|
if rule == "":
|
||||||
logger.error("Cannot create container with empty placement 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)
|
logger.info("Cmd: %s" % createContainerCmd)
|
||||||
try:
|
try:
|
||||||
complProc = subprocess.run(createContainerCmd, check=True, universal_newlines=True,
|
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
|
output = complProc.stdout
|
||||||
logger.info("Output: %s" % output)
|
logger.info("Output: %s" % output)
|
||||||
cid = _parse_cid(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 expected_objects_list:
|
||||||
if sorted(found_objects) == sorted(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:
|
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
|
return found_objects
|
||||||
|
|
||||||
|
@ -550,7 +540,7 @@ def _get_raw_split_information(header):
|
||||||
result_header['Type'] = m.group(1)
|
result_header['Type'] = m.group(1)
|
||||||
else:
|
else:
|
||||||
raise Exception("no Type was parsed from object header: \t%s" % header)
|
raise Exception("no Type was parsed from object header: \t%s" % header)
|
||||||
|
|
||||||
# PayloadLength
|
# PayloadLength
|
||||||
m = re.search(r'Size: (\d+)', header)
|
m = re.search(r'Size: (\d+)', header)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
|
@ -581,7 +571,7 @@ def _get_raw_split_information(header):
|
||||||
result_header['Split ChildID'] = found_objects
|
result_header['Split ChildID'] = found_objects
|
||||||
logger.info("Result: %s" % result_header)
|
logger.info("Result: %s" % result_header)
|
||||||
|
|
||||||
return result_header
|
return result_header
|
||||||
|
|
||||||
@keyword('Verify Head Tombstone')
|
@keyword('Verify Head Tombstone')
|
||||||
def verify_head_tombstone(private_key: str, cid: str, oid_ts: str, oid: str, addr: str):
|
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
|
result_header["PayloadLength"] = PayloadLength
|
||||||
else:
|
else:
|
||||||
raise Exception("no PayloadLength was parsed from header: \t%s" % header)
|
raise Exception("no PayloadLength was parsed from header: \t%s" % header)
|
||||||
|
|
||||||
|
|
||||||
# HomoHash
|
# HomoHash
|
||||||
HomoHash = json_header["header"]["homomorphicHash"]["sum"]
|
HomoHash = json_header["header"]["homomorphicHash"]["sum"]
|
||||||
|
@ -770,14 +760,14 @@ def decode_object_system_header_json(header):
|
||||||
Checksum_64_d = base64.b64decode(Checksum)
|
Checksum_64_d = base64.b64decode(Checksum)
|
||||||
result_header["Checksum"] = binascii.hexlify(Checksum_64_d)
|
result_header["Checksum"] = binascii.hexlify(Checksum_64_d)
|
||||||
else:
|
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
|
||||||
Type = json_header["header"]["objectType"]
|
Type = json_header["header"]["objectType"]
|
||||||
if Type is not None:
|
if Type is not None:
|
||||||
result_header["Type"] = Type
|
result_header["Type"] = Type
|
||||||
else:
|
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
|
# Header - Optional attributes
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import subprocess
|
import os
|
||||||
import pexpect
|
import pexpect
|
||||||
import re
|
import re
|
||||||
import uuid
|
|
||||||
import requests
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
|
|
||||||
from robot.api.deco import keyword
|
from robot.api.deco import keyword
|
||||||
from robot.api import logger
|
from robot.api import logger
|
||||||
import robot.errors
|
from neo3 import wallet
|
||||||
from robot.libraries.BuiltIn import BuiltIn
|
|
||||||
|
|
||||||
from common import *
|
from common import *
|
||||||
|
import rpc_client
|
||||||
|
|
||||||
ROBOT_AUTO_KEYWORDS = False
|
ROBOT_AUTO_KEYWORDS = False
|
||||||
|
|
||||||
# path to neofs-cli executable
|
# 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')
|
@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')
|
@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.
|
This function return True in case of accepted TX.
|
||||||
Parameters:
|
Parameters:
|
||||||
:param tx_id: transaction is
|
:param tx_id: transaction ID
|
||||||
:rtype: block number or Exception
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger.info("Transaction id: %s" % tx_id)
|
try:
|
||||||
|
resp = mainnet_rpc_cli.get_transaction_height(tx_id)
|
||||||
headers = {'Content-type': 'application/json'}
|
if resp is not None:
|
||||||
data = { "jsonrpc": "2.0", "id": 5, "method": "gettransactionheight", "params": [ tx_id ] }
|
logger.info(f"got block height: {resp}")
|
||||||
response = requests.post(NEO_MAINNET_ENDPOINT, json=data, headers=headers, verify=False)
|
return True
|
||||||
|
except Exception as e:
|
||||||
if not response.ok:
|
logger.info(f"request failed with error: {e}")
|
||||||
raise Exception(f"""Failed:
|
raise e
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
@keyword('Get NeoFS Balance')
|
@keyword('Get NeoFS Balance')
|
||||||
def get_balance(privkey: str):
|
def get_balance(wif: str):
|
||||||
"""
|
"""
|
||||||
This function returns NeoFS balance for selected public key.
|
This function returns NeoFS balance for given WIF.
|
||||||
:param public_key: neo public key
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
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):
|
def _run_sh_with_passwd(passwd, cmd):
|
||||||
p = pexpect.spawn(cmd)
|
p = pexpect.spawn(cmd)
|
||||||
|
|
|
@ -41,5 +41,5 @@ Payment Operations
|
||||||
# For certainty, sleeping during one morph block.
|
# For certainty, sleeping during one morph block.
|
||||||
Sleep ${MORPH_BLOCK_TIME}
|
Sleep ${MORPH_BLOCK_TIME}
|
||||||
|
|
||||||
${NEOFS_BALANCE} = Get NeoFS Balance ${WIF}
|
${NEOFS_BALANCE} = Get NeoFS Balance ${WIF}
|
||||||
Should Be Equal As Numbers ${NEOFS_BALANCE} ${DEPOSIT_AMOUNT}
|
Should Be Equal As Numbers ${NEOFS_BALANCE} ${DEPOSIT_AMOUNT}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python3.7
|
#!/usr/bin/python3.8
|
||||||
|
|
||||||
import docker
|
import docker
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -85,10 +85,10 @@ Generate Key and Pre-payment
|
||||||
Validate Policy
|
Validate Policy
|
||||||
[Arguments] ${POLICY} ${EXPECTED_VAL} @{EXPECTED_LIST}
|
[Arguments] ${POLICY} ${EXPECTED_VAL} @{EXPECTED_LIST}
|
||||||
|
|
||||||
Log Container with rule ${POLICY}
|
Log Container with rule ${POLICY}
|
||||||
|
|
||||||
${CID} = Create container ${PRIV_KEY} ${EMPTY} ${POLICY}
|
${CID} = Create container ${PRIV_KEY} ${EMPTY} ${POLICY}
|
||||||
Container Existing ${PRIV_KEY} ${CID}
|
Container Existing ${PRIV_KEY} ${CID}
|
||||||
${S_OID} = Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${EMPTY}
|
${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
|
Get object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read
|
||||||
|
|
|
@ -3,6 +3,7 @@ Variables ../../../variables/common.py
|
||||||
|
|
||||||
Library ../${RESOURCES}/neofs.py
|
Library ../${RESOURCES}/neofs.py
|
||||||
Library ../${RESOURCES}/payment_neogo.py
|
Library ../${RESOURCES}/payment_neogo.py
|
||||||
|
Library ${KEYWORDS}/contract_keywords.py
|
||||||
|
|
||||||
Resource common_steps_object.robot
|
Resource common_steps_object.robot
|
||||||
Resource ../${RESOURCES}/payment_operations.robot
|
Resource ../${RESOURCES}/payment_operations.robot
|
||||||
|
|
|
@ -16,7 +16,7 @@ ABSOLUTE_FILE_PATH="/robot/testsuites/integration"
|
||||||
NEOFS_EPOCH_TIMEOUT = (os.getenv("NEOFS_EPOCH_TIMEOUT") if os.getenv("NEOFS_EPOCH_TIMEOUT")
|
NEOFS_EPOCH_TIMEOUT = (os.getenv("NEOFS_EPOCH_TIMEOUT") if os.getenv("NEOFS_EPOCH_TIMEOUT")
|
||||||
else os.getenv("NEOFS_IR_TIMERS_EPOCH", "300s"))
|
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")
|
COMPLEX_OBJ_SIZE = os.getenv("COMPLEX_OBJ_SIZE", "70000000")
|
||||||
|
|
||||||
MAINNET_BLOCK_TIME = os.getenv('MAINNET_BLOCK_TIME', "15s")
|
MAINNET_BLOCK_TIME = os.getenv('MAINNET_BLOCK_TIME', "15s")
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue