forked from TrueCloudLab/frostfs-testcases
Merged feature-dev2 into master [DRAFT]
This commit is contained in:
commit
1498089c1f
11 changed files with 1226 additions and 144 deletions
|
@ -71,11 +71,7 @@ RUN apk add --no-cache git \
|
|||
RUN mkdir -p /robot/vendor
|
||||
|
||||
RUN cd /robot/vendor \
|
||||
&& git clone git@bitbucket.org:nspcc-dev/neofs-dev-env.git \
|
||||
&& cd neofs-dev-env \
|
||||
&& cp ca/* /usr/local/share/ca-certificates/ \
|
||||
&& update-ca-certificates
|
||||
|
||||
&& git clone https://github.com/nspcc-dev/neofs-dev-env.git
|
||||
|
||||
WORKDIR ${WD}
|
||||
COPY ./ ${WD}
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.0.17
|
||||
VERSION=0.0.18
|
||||
PREFIX=
|
||||
|
||||
B=\033[0;1m
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
|
||||
При этом должен быть запущен dev-env с тестируемым окружением.
|
||||
|
||||
Из корня dev-env выполнить команду:
|
||||
```
|
||||
docker cp wallets/wallet.json main_chain:/wallets/
|
||||
```
|
||||
|
||||
2. Выпольнить `make run`
|
||||
|
||||
3. Логи будут доступны в папке artifacts/ после завершения тестов с любым из статусов.
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
dockerd &
|
||||
sleep 60
|
||||
export DOCKER_HOST=unix:///var/run/docker.sock
|
||||
docker login registry.nspcc.ru -u ${REG_USR} -p ${REG_PWD}
|
||||
make hosts -B -C /robot/vendor/neofs-dev-env | grep -v make >> /etc/hosts
|
||||
make rebuild -C /robot/vendor/neofs-dev-env
|
||||
make up -C /robot/vendor/neofs-dev-env
|
||||
sleep 60
|
||||
robot --timestampoutputs --outputdir /artifacts/ /robot/testsuites/integration/object_suite.robot
|
||||
robot --timestampoutputs --outputdir /artifacts/ /robot/testsuites/integration/*.robot
|
||||
|
|
|
@ -17,7 +17,7 @@ from neocore.KeyPair import KeyPair
|
|||
from Crypto import Random
|
||||
|
||||
ROBOT_AUTO_KEYWORDS = False
|
||||
NEOFS_NEO_API_ENDPOINT = "https://fs.localtest.nspcc.ru/neo_rpc/"
|
||||
NEOFS_NEO_API_ENDPOINT = "main_chain.neofs.devenv:30333"
|
||||
|
||||
@keyword('Generate Neo private key')
|
||||
def generate_neo_private_key():
|
||||
|
@ -55,50 +55,8 @@ def get_neo_address(private_key: bytes):
|
|||
"""
|
||||
keypair_gen = KeyPair(private_key)
|
||||
address = keypair_gen.GetAddress()
|
||||
wif = keypair_gen.Export()
|
||||
logger.info("Generated Neo address: %s" % address)
|
||||
logger.info("Generated WIF: %s" % wif)
|
||||
return address
|
||||
|
||||
@keyword('Transaction accepted in block')
|
||||
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
|
||||
"""
|
||||
|
||||
logger.info("Transaction id: %s" % tx_id)
|
||||
m = re.match(r"^\"0x+([\w.]+)", tx_id)
|
||||
if m is None:
|
||||
BuiltIn().fatal_error('Can not parse transaction id: "%s"' % tx_id)
|
||||
|
||||
TX_request = 'curl -X POST '+NEOFS_NEO_API_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "gettransactionheight", "params": [\"'+m.group(1)+'\"] }\''
|
||||
complProc = subprocess.run(TX_request, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
logger.info(complProc.stdout)
|
||||
response = json.loads(complProc.stdout)
|
||||
|
||||
if (response['result'] == 0):
|
||||
raise Exception( "Transaction is not found in the blocks." )
|
||||
|
||||
logger.info("Transaction has been found in the block %s." % response['result'] )
|
||||
return response['result']
|
||||
|
||||
|
||||
@keyword('Get Transaction')
|
||||
def get_transaction(tx_id: str):
|
||||
"""
|
||||
This function return information about TX.
|
||||
Parameters:
|
||||
:param tx_id: transaction id
|
||||
"""
|
||||
|
||||
m = re.match(r"^\"0x+([\w.]+)", tx_id)
|
||||
if m is None:
|
||||
BuiltIn().fatal_error('Can not parse transaction id: "%s"' % tx_id)
|
||||
|
||||
TX_request = 'curl -X POST '+NEOFS_NEO_API_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "getapplicationlog", "params": [\"'+m.group(1)+'\"] }\''
|
||||
complProc = subprocess.run(TX_request, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
logger.info(complProc.stdout)
|
||||
|
|
@ -12,16 +12,51 @@ from robot.api import logger
|
|||
|
||||
ROBOT_AUTO_KEYWORDS = False
|
||||
|
||||
NEOFS_ENDPOINT = "192.168.123.71:8080"
|
||||
CLI_PREFIX = "docker exec neofs-cli "
|
||||
NEOFS_ENDPOINT = "s01.neofs.devenv:8080"
|
||||
CLI_PREFIX = ""
|
||||
|
||||
@keyword('Form WIF from String')
|
||||
def form_wif_from_string(private_key: str):
|
||||
wif = ""
|
||||
Cmd = f'neofs-cli util keyer -u {private_key}'
|
||||
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'WIF\s+(\w+)', output)
|
||||
if m.start() != m.end():
|
||||
wif = m.group(1)
|
||||
else:
|
||||
raise Exception("Can not get WIF.")
|
||||
|
||||
return wif
|
||||
|
||||
|
||||
@keyword('Get ScripHash')
|
||||
def get_scripthash(privkey: str):
|
||||
scripthash = ""
|
||||
Cmd = f'neofs-cli 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)
|
||||
|
||||
# ScriptHash3.0 00284fc88f8ac31f8e56c03301bfab0757e3f212
|
||||
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('Form Privkey from String')
|
||||
def form_privkey_from_string(private_key: str):
|
||||
return bytes.fromhex(private_key)
|
||||
|
||||
|
||||
@keyword('Get nodes with object')
|
||||
def get_nodes_with_object(private_key: bytes, cid, oid):
|
||||
def get_nodes_with_object(private_key: str, cid, oid):
|
||||
storage_nodes = _get_storage_nodes(private_key)
|
||||
copies = 0
|
||||
|
||||
|
@ -30,14 +65,14 @@ def get_nodes_with_object(private_key: bytes, cid, oid):
|
|||
for node in storage_nodes:
|
||||
search_res = _search_object(node, private_key, cid, oid)
|
||||
if search_res:
|
||||
if re.search(r'(%s: %s)' % (cid, oid), search_res):
|
||||
if re.search(r'(%s)' % (oid), search_res):
|
||||
nodes_list.append(node)
|
||||
|
||||
logger.info("Nodes with object: %s" % nodes_list)
|
||||
|
||||
|
||||
@keyword('Get nodes without object')
|
||||
def get_nodes_without_object(private_key: bytes, cid, oid):
|
||||
def get_nodes_without_object(private_key: str, cid, oid):
|
||||
storage_nodes = _get_storage_nodes(private_key)
|
||||
copies = 0
|
||||
|
||||
|
@ -46,7 +81,7 @@ def get_nodes_without_object(private_key: bytes, cid, oid):
|
|||
for node in storage_nodes:
|
||||
search_res = _search_object(node, private_key, cid, oid)
|
||||
if search_res:
|
||||
if not re.search(r'(%s: %s)' % (cid, oid), search_res):
|
||||
if not re.search(r'(%s)' % (oid), search_res):
|
||||
nodes_list.append(node)
|
||||
else:
|
||||
nodes_list.append(node)
|
||||
|
@ -55,7 +90,7 @@ def get_nodes_without_object(private_key: bytes, cid, oid):
|
|||
|
||||
|
||||
@keyword('Validate storage policy for object')
|
||||
def validate_storage_policy_for_object(private_key: bytes, expected_copies: int, cid, oid, *expected_node_list):
|
||||
def validate_storage_policy_for_object(private_key: str, expected_copies: int, cid, oid, *expected_node_list):
|
||||
storage_nodes = _get_storage_nodes(private_key)
|
||||
copies = 0
|
||||
found_nodes = []
|
||||
|
@ -63,7 +98,7 @@ def validate_storage_policy_for_object(private_key: bytes, expected_copies: int,
|
|||
for node in storage_nodes:
|
||||
search_res = _search_object(node, private_key, cid, oid)
|
||||
if search_res:
|
||||
if re.search(r'(%s: %s)' % (cid, oid), search_res):
|
||||
if re.search(r'(%s)' % (oid), search_res):
|
||||
copies += 1
|
||||
found_nodes.append(node)
|
||||
|
||||
|
@ -132,13 +167,13 @@ def set_eacl(private_key: bytes, cid: str, eacl: str):
|
|||
|
||||
|
||||
@keyword('Get Range')
|
||||
def get_range(private_key: bytes, cid: str, oid: str, bearer: str, range_cut: str):
|
||||
def get_range(private_key: str, cid: str, oid: str, bearer: str, range_cut: str):
|
||||
|
||||
bearer_token = ""
|
||||
if bearer:
|
||||
bearer_token = f"--bearer {bearer}"
|
||||
|
||||
Cmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object get-range --cid {cid} --oid {oid} {bearer_token} {range_cut} '
|
||||
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,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
|
||||
|
@ -147,12 +182,12 @@ def get_range(private_key: bytes, cid: str, oid: str, bearer: str, range_cut: st
|
|||
|
||||
|
||||
@keyword('Create container')
|
||||
def create_container(private_key: bytes, basic_acl:str="", rule:str="RF 2 SELECT 2 Node"):
|
||||
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 = "--acl " + basic_acl
|
||||
basic_acl = "--basic-acl " + basic_acl
|
||||
|
||||
createContainerCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} container put --rule "{rule}" {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,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
|
||||
|
@ -161,13 +196,17 @@ def create_container(private_key: bytes, basic_acl:str="", rule:str="RF 2 SELECT
|
|||
cid = _parse_cid(output)
|
||||
logger.info("Created container %s with rule '%s'" % (cid, rule))
|
||||
|
||||
#$ ./bin/neofs-cli -c config.yml container create --policy rule.ql --await
|
||||
#container ID: GePis2sDpYqYPh4F8vfGUqoujtNcqdXhipbLx2pKbUwX
|
||||
|
||||
# REP 1 IN X CBF 1 SELECT 2 IN SAME Location FROM * AS X
|
||||
return cid
|
||||
|
||||
|
||||
@keyword('Container Existing')
|
||||
def container_existing(private_key: bytes, cid: str):
|
||||
Cmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} container list'
|
||||
logger.info("CMD: %s" % Cmd)
|
||||
def container_existing(private_key: str, cid: str):
|
||||
Cmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} container list'
|
||||
logger.info("Cmd: %s" % Cmd)
|
||||
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)
|
||||
|
@ -195,18 +234,17 @@ def generate_file_of_bytes(size):
|
|||
|
||||
|
||||
@keyword('Search object')
|
||||
def search_object(private_key: bytes, cid: str, keys: str, bearer: str, *expected_objects_list, **kwargs ):
|
||||
def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: str, *expected_objects_list ):
|
||||
|
||||
bearer_token = ""
|
||||
if bearer:
|
||||
bearer_token = f"--bearer {bearer}"
|
||||
|
||||
option = ""
|
||||
if kwargs:
|
||||
for key, value in dict(kwargs).items():
|
||||
option = f'{option} {key} {value}'
|
||||
|
||||
ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object search {keys} --cid {cid} {bearer_token} {option}'
|
||||
if filters:
|
||||
filters = f"--filters {filters}"
|
||||
|
||||
ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object search {keys} --cid {cid} {bearer_token} {filters}'
|
||||
logger.info("Cmd: %s" % ObjectCmd)
|
||||
try:
|
||||
complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
|
||||
|
@ -215,8 +253,9 @@ def search_object(private_key: bytes, cid: str, keys: str, bearer: str, *expecte
|
|||
logger.info("Output: %s" % complProc.stdout)
|
||||
|
||||
if expected_objects_list:
|
||||
found_objects = re.findall(r'%s: ([\-\w]+)' % cid, complProc.stdout)
|
||||
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:
|
||||
|
@ -229,7 +268,7 @@ def search_object(private_key: bytes, cid: str, keys: str, bearer: str, *expecte
|
|||
|
||||
|
||||
@keyword('Verify Head Tombstone')
|
||||
def verify_head_tombstone(private_key: bytes, cid: str, oid: str):
|
||||
def verify_head_tombstone(private_key: str, cid: str, oid: str):
|
||||
|
||||
ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object head --cid {cid} --oid {oid} --full-headers'
|
||||
logger.info("Cmd: %s" % ObjectCmd)
|
||||
|
@ -350,28 +389,26 @@ def _check_linked_object(obj:str, child_obj_list_headers:dict, payload_size:int,
|
|||
|
||||
|
||||
@keyword('Head object')
|
||||
def head_object(private_key: bytes, cid: str, oid: str, bearer: str, full_headers:bool=False, **user_headers_dict):
|
||||
def head_object(private_key: str, cid: str, oid: str, bearer: str, user_headers:str=""):
|
||||
options = ""
|
||||
if full_headers:
|
||||
options = "--full-headers"
|
||||
|
||||
bearer_token = ""
|
||||
if bearer:
|
||||
bearer_token = f"--bearer {bearer}"
|
||||
|
||||
ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object head --cid {cid} --oid {oid} {bearer_token} {options}'
|
||||
ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object head --cid {cid} --oid {oid} {bearer_token} {options}'
|
||||
logger.info("Cmd: %s" % ObjectCmd)
|
||||
try:
|
||||
complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
logger.info("Output: %s" % complProc.stdout)
|
||||
|
||||
for key in user_headers_dict:
|
||||
user_header = f'Key={key} Val={user_headers_dict[key]}'
|
||||
if re.search(r'(%s)' % user_header, complProc.stdout):
|
||||
logger.info("User header %s was parsed from command output" % user_header)
|
||||
for key in user_headers.split(","):
|
||||
# user_header = f'Key={key} Val={user_headers_dict[key]}'
|
||||
if re.search(r'(%s)' % key, complProc.stdout):
|
||||
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" % (user_header, complProc.stdout))
|
||||
raise Exception("User header %s was not found in the command output: \t%s" % (key, complProc.stdout))
|
||||
|
||||
return complProc.stdout
|
||||
|
||||
|
@ -464,13 +501,13 @@ def parse_object_extended_header(header: str):
|
|||
|
||||
|
||||
@keyword('Delete object')
|
||||
def delete_object(private_key: bytes, cid: str, oid: str, bearer: str):
|
||||
def delete_object(private_key: str, cid: str, oid: str, bearer: str):
|
||||
|
||||
bearer_token = ""
|
||||
if bearer:
|
||||
bearer_token = f"--bearer {bearer}"
|
||||
|
||||
ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object delete --cid {cid} --oid {oid} {bearer_token}'
|
||||
ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object delete --cid {cid} --oid {oid} {bearer_token}'
|
||||
try:
|
||||
complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
|
@ -536,29 +573,16 @@ def cleanup_file(filename: str):
|
|||
|
||||
|
||||
@keyword('Put object to NeoFS')
|
||||
def put_object(private_key: bytes, path: str, cid: str, bearer: str, **kwargs):
|
||||
def put_object(private_key: str, path: str, cid: str, bearer: str, user_headers: str):
|
||||
logger.info("Going to put the object")
|
||||
|
||||
user_headers = ""
|
||||
user_headers_dict = kwargs
|
||||
if kwargs:
|
||||
logger.info(kwargs)
|
||||
for key, value in dict(kwargs).items():
|
||||
user_headers = f'{user_headers} --user "{key}"="{value}"'
|
||||
if user_headers:
|
||||
user_headers = f"--attributes {user_headers}"
|
||||
|
||||
bearer_token = ""
|
||||
if bearer:
|
||||
bearer_token = f"--bearer {bearer}"
|
||||
bearer = f"--bearer {bearer}"
|
||||
|
||||
|
||||
# Put object to cli container
|
||||
putObjectCont = f'docker cp {path} neofs-cli:/ '
|
||||
logger.info("Cmd: %s" % putObjectCont)
|
||||
complProc = subprocess.run(putObjectCont, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=60, shell=True)
|
||||
|
||||
|
||||
putObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object put --verify --file {path} --cid {cid} {bearer_token} {user_headers}'
|
||||
putObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object put --file {path} --cid {cid} {bearer} {user_headers}'
|
||||
logger.info("Cmd: %s" % putObjectCmd)
|
||||
complProc = subprocess.run(putObjectCmd, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=60, shell=True)
|
||||
|
@ -567,17 +591,13 @@ def put_object(private_key: bytes, path: str, cid: str, bearer: str, **kwargs):
|
|||
return oid
|
||||
|
||||
|
||||
@keyword('Get object from NeoFS')
|
||||
def get_object(private_key: bytes, cid: str, oid: str, bearer: str, read_object: str):
|
||||
|
||||
bearer_token = ""
|
||||
if bearer:
|
||||
@keyword('Get Range Hash')
|
||||
def get_range_hash(private_key: str, cid: str, oid: str, bearer_token: str, range_cut: str):
|
||||
|
||||
if bearer_token:
|
||||
bearer_token = f"--bearer {bearer}"
|
||||
|
||||
|
||||
ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} object get --cid {cid} --oid {oid} --file {read_object} {bearer_token}'
|
||||
|
||||
|
||||
|
||||
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)
|
||||
try:
|
||||
|
@ -587,11 +607,22 @@ def get_object(private_key: bytes, cid: str, oid: str, bearer: str, read_object:
|
|||
except subprocess.CalledProcessError as e:
|
||||
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
|
||||
|
||||
# Get object from cli container
|
||||
getObjectCont = f'docker cp neofs-cli:/{read_object} . '
|
||||
logger.info("Cmd: %s" % getObjectCont)
|
||||
complProc = subprocess.run(getObjectCont, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=60, shell=True)
|
||||
|
||||
@keyword('Get object from NeoFS')
|
||||
def get_object(private_key: str, cid: str, oid: str, bearer_token: str, read_object: str):
|
||||
|
||||
if bearer_token:
|
||||
bearer_token = f"--bearer {bearer_token}"
|
||||
|
||||
ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object get --cid {cid} --oid {oid} --file {read_object} {bearer_token}'
|
||||
|
||||
logger.info("Cmd: %s" % ObjectCmd)
|
||||
try:
|
||||
complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=60, 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))
|
||||
|
||||
|
||||
def _get_file_hash(filename):
|
||||
|
@ -637,44 +668,52 @@ def _parse_cid(output: str):
|
|||
Parameters:
|
||||
- output: a string with command run output
|
||||
"""
|
||||
m = re.search(r'Success! Container <(([a-zA-Z0-9])+)> created', output)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
cid = m.group(1)
|
||||
else:
|
||||
m = re.search(r'container ID: (\w+)', output)
|
||||
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):
|
||||
storage_nodes = []
|
||||
NetmapCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} status netmap'
|
||||
complProc = subprocess.run(NetmapCmd, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
output = complProc.stdout
|
||||
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))
|
||||
storage_nodes = ['s01.neofs.devenv:8080', 's02.neofs.devenv:8080','s03.neofs.devenv:8080','s04.neofs.devenv:8080']
|
||||
#NetmapCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} status netmap'
|
||||
#complProc = subprocess.run(NetmapCmd, check=True, universal_newlines=True,
|
||||
# stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
#output = complProc.stdout
|
||||
#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.")
|
||||
#if not storage_nodes:
|
||||
# raise Exception("Storage nodes was not found.")
|
||||
|
||||
|
||||
# Will be fixed when netmap will be added to cli
|
||||
|
||||
#storage_nodes.append()
|
||||
logger.info("Storage nodes: %s" % storage_nodes)
|
||||
return storage_nodes
|
||||
|
||||
|
||||
def _search_object(node:str, private_key: bytes, cid:str, oid: str):
|
||||
Cmd = f'{CLI_PREFIX}neofs-cli --host {node} --ttl 1 --key {binascii.hexlify(private_key).decode()} object search --root --cid {cid} ID {oid}'
|
||||
def _search_object(node:str, private_key: str, cid:str, oid: str):
|
||||
# --filters objectID={oid}
|
||||
Cmd = f'{CLI_PREFIX}neofs-cli --rpc-endpoint {node} --key {private_key} --ttl 1 object search --root --cid {cid} '
|
||||
|
||||
try:
|
||||
logger.info(Cmd)
|
||||
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)
|
||||
return complProc.stdout
|
||||
|
||||
if re.search(r'%s' % oid, complProc.stdout):
|
||||
return oid
|
||||
else:
|
||||
logger.info("Object is not found.")
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
if "FailedPrecondition: server is not presented in container" in e.output:
|
||||
logger.info("FailedPrecondition: server is not presented in container.")
|
||||
if re.search(r'local node is outside of object placement', e.output):
|
||||
logger.info("Server is not presented in container.")
|
||||
else:
|
||||
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
|
||||
|
||||
|
|
386
robot/resources/lib/payment_neogo.py
Normal file
386
robot/resources/lib/payment_neogo.py
Normal file
|
@ -0,0 +1,386 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import subprocess
|
||||
import pexpect
|
||||
import re
|
||||
import uuid
|
||||
|
||||
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
|
||||
|
||||
from Crypto import Random
|
||||
|
||||
ROBOT_AUTO_KEYWORDS = False
|
||||
|
||||
|
||||
|
||||
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():
|
||||
|
||||
filename = "wallets/" + str(uuid.uuid4()) + ".json"
|
||||
cmd = ( f"{NEOGO_CLI_PREFIX} wallet init -w {filename}" )
|
||||
|
||||
logger.info(f"Executing shell command: {cmd}")
|
||||
out = run_sh(cmd)
|
||||
logger.info(f"Command completed with output: {out}")
|
||||
return filename
|
||||
|
||||
@keyword('Generate wallet')
|
||||
def generate_wallet(wallet: str):
|
||||
cmd = ( f"{NEOGO_CLI_PREFIX} wallet create -w {wallet}" )
|
||||
|
||||
logger.info(f"Executing command: {cmd}")
|
||||
p = pexpect.spawn(cmd)
|
||||
p.expect(".*")
|
||||
p.sendline('\n')
|
||||
p.sendline('\n')
|
||||
p.sendline('\n')
|
||||
p.wait()
|
||||
out = p.read()
|
||||
|
||||
logger.info(f"Command completed with output: {out}")
|
||||
|
||||
@keyword('Dump Address')
|
||||
def dump_address(wallet: str):
|
||||
#"address": "Ngde6LSaBZ58p72trTNkgqEZmX8dTWBgHo",
|
||||
address = ""
|
||||
cmd = ( f"{NEOGO_CLI_PREFIX} wallet dump -w {wallet}" )
|
||||
|
||||
logger.info(f"Executing command: {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():
|
||||
address = m.group(1)
|
||||
else:
|
||||
raise Exception("Can not get address.")
|
||||
|
||||
return address
|
||||
|
||||
@keyword('Dump PrivKey')
|
||||
def dump_privkey(wallet: str, address: str):
|
||||
cmd = ( f"{NEOGO_CLI_PREFIX} wallet export -w {wallet} --decrypt {address}" )
|
||||
|
||||
logger.info(f"Executing command: {cmd}")
|
||||
out = run_sh_with_passwd('', cmd)
|
||||
logger.info(f"Command completed with output: {out}")
|
||||
|
||||
return out
|
||||
|
||||
|
||||
@keyword('Transfer Mainnet Gas')
|
||||
# docker cp wallets/wallet.json main_chain:/wallets/
|
||||
|
||||
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}" )
|
||||
|
||||
logger.info(f"Executing command: {cmd}")
|
||||
out = run_sh_with_passwd('', cmd)
|
||||
logger.info(f"Command completed with output: {out}")
|
||||
|
||||
if not re.match(r'^(\w{64})$', out):
|
||||
raise Exception("Can not get Tx.")
|
||||
|
||||
return out
|
||||
|
||||
@keyword('Withdraw Mainnet Gas')
|
||||
# docker cp wallets/wallet.json main_chain:/wallets/
|
||||
|
||||
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}" )
|
||||
|
||||
logger.info(f"Executing command: {cmd}")
|
||||
out = run_sh_with_passwd('', cmd)
|
||||
logger.info(f"Command completed with output: {out}")
|
||||
|
||||
#if not re.match(r'^(\w{64})$', out):
|
||||
# raise Exception("Can not get Tx.")
|
||||
|
||||
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+'\"] }\''
|
||||
logger.info(f"Executing request: {request}")
|
||||
|
||||
complProc = subprocess.run(request, check=True, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
|
||||
|
||||
out = complProc.stdout
|
||||
logger.info(out)
|
||||
|
||||
m = re.search(r'"668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","amount":"([\d\.]+)"', out)
|
||||
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):
|
||||
cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} "
|
||||
f"-r http://main_chain.neofs.devenv:30333 {NEOFS_CONTRACT} "
|
||||
f"deposit {scripthash} int:{amount} bytes: -- {scripthash}")
|
||||
|
||||
logger.info(f"Executing command: {cmd}")
|
||||
out = run_sh_with_passwd('', cmd)
|
||||
logger.info(f"Command completed with output: {out}")
|
||||
|
||||
m = re.match(r'^Sent invocation transaction (\w{64})$', out)
|
||||
if m is None:
|
||||
raise Exception("Can not get Tx.")
|
||||
|
||||
tx = m.group(1)
|
||||
|
||||
# Sent invocation transaction
|
||||
|
||||
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 <http://main_chain.neofs.devenv:30333> 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):
|
||||
"""
|
||||
This function return True in case of accepted TX.
|
||||
Parameters:
|
||||
:param tx_id: transaction is
|
||||
:rtype: block number or Exception
|
||||
"""
|
||||
|
||||
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)
|
||||
logger.info(complProc.stdout)
|
||||
response = json.loads(complProc.stdout)
|
||||
|
||||
if (response['result'] == 0):
|
||||
raise Exception( "Transaction is not found in the blocks." )
|
||||
|
||||
logger.info("Transaction has been found in the block %s." % response['result'] )
|
||||
return response['result']
|
||||
|
||||
|
||||
@keyword('Get Transaction')
|
||||
def get_transaction(tx_id: str):
|
||||
"""
|
||||
This function return information about TX.
|
||||
Parameters:
|
||||
:param tx_id: transaction id
|
||||
"""
|
||||
|
||||
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": "getapplicationlog", "params": [\"'+tx_id+'\"] }\''
|
||||
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,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
timeout=150, shell=True)
|
||||
output, errors = complProc.stdout, complProc.stderr
|
||||
if errors:
|
||||
return errors
|
||||
return output
|
||||
|
||||
|
||||
def run_sh_with_passwd(passwd, cmd):
|
||||
p = pexpect.spawn(cmd)
|
||||
p.expect(".*")
|
||||
p.sendline(passwd)
|
||||
p.wait()
|
||||
# throw a string with password prompt
|
||||
# take a string with tx hash
|
||||
tx_hash = p.read().splitlines()[-1]
|
||||
return tx_hash.decode()
|
||||
|
||||
|
||||
|
||||
#@keyword('Transfer Mainnet Gas')
|
||||
#def transfer_mainnet_gas(wallet_to: str, amount: int):
|
||||
|
||||
#
|
||||
# Cmd = f'docker exec -it main_chain neo-go wallet nep5 transfer -w wallets/wallet.json -r http://main_chain.neofs.devenv:30333 --from NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx --to {wallet_to} --token gas --amount {amount}'
|
||||
# command = ['docker', 'exec', '-it', 'main_chain', 'neo-go', 'wallet', 'nep5', 'transfer', '-w', 'wallets/wallet.json', '-r', 'http://main_chain.neofs.devenv:30333', '--from NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx', '--to', 'NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt', '--token gas', '--amount', '5']
|
||||
|
||||
|
||||
|
||||
# logger.info("Cmd: %s" % Cmd)
|
||||
|
||||
#import subprocess
|
||||
#command = ['myapp', '--arg1', 'value_for_arg1']
|
||||
#p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
#output = p.communicate(input='some data'.encode())[0]
|
||||
|
||||
#a=subprocess.Popen("docker run -t -i fedora bash", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
#4. >>> a.stdin.write("exit\n")
|
||||
#5. >>> print a.poll()
|
||||
|
||||
complProc = subprocess.Popen(Cmd.split(), stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
||||
complProc.stdin.write("\n".encode())
|
||||
|
||||
output = complProc.stdout.read() #.communicate(input=''.encode())[0]
|
||||
|
||||
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):
|
||||
"""
|
||||
This function requests Deposit to the selected public key.
|
||||
:param public_key: neo public key
|
||||
"""
|
||||
|
||||
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:
|
||||
logger.info("Deposit has been completed for '%s'; tx: '%s'" % (public_key, response.text) )
|
||||
|
||||
return response.text
|
||||
|
||||
@keyword('Get Balance')
|
||||
def get_balance(privkey: str):
|
||||
"""
|
||||
This function returns NeoFS balance for selected public key.
|
||||
:param public_key: neo public key
|
||||
"""
|
||||
|
||||
balance = _get_balance_request(privkey)
|
||||
|
||||
return balance
|
||||
|
||||
@keyword('Expected Balance')
|
||||
def expected_balance(privkey: str, init_amount: float, deposit_size: float):
|
||||
"""
|
||||
This function returns NeoFS balance for selected public key.
|
||||
:param public_key: neo public key
|
||||
:param init_amount: initial number of tokens in the account
|
||||
:param deposit_size: expected amount of the balance increasing
|
||||
"""
|
||||
|
||||
balance = _get_balance_request(privkey)
|
||||
|
||||
deposit_change = round((float(balance) - init_amount),8)
|
||||
if deposit_change != deposit_size:
|
||||
raise Exception('Expected deposit increase: {}. This does not correspond to the actual change in account: {}'.format(deposit_size, deposit_change))
|
||||
|
||||
logger.info('Expected deposit increase: {}. This correspond to the actual change in account: {}'.format(deposit_size, deposit_change))
|
||||
|
||||
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'
|
||||
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)
|
||||
balance = m.group(1)
|
||||
|
||||
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":[]}}
|
268
robot/testsuites/integration/acl_basic_api2.robot
Normal file
268
robot/testsuites/integration/acl_basic_api2.robot
Normal file
|
@ -0,0 +1,268 @@
|
|||
*** Settings ***
|
||||
Variables ../../variables/common.py
|
||||
|
||||
|
||||
Library ${RESOURCES}/environment.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
Library ${RESOURCES}/neofs.py
|
||||
Library ${RESOURCES}/payment_neogo.py
|
||||
Library ${RESOURCES}/assertions.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
|
||||
*** Variables ***
|
||||
${RULE_FOR_ALL} = REP 2 IN X CBF 1 SELECT 4 FROM * AS X
|
||||
|
||||
|
||||
*** Test cases ***
|
||||
Basic ACL Operations
|
||||
[Documentation] Testcase to validate NeoFS operations with ACL.
|
||||
[Tags] ACL NeoFS NeoCLI
|
||||
[Timeout] 20 min
|
||||
|
||||
Generate Keys
|
||||
Create Containers
|
||||
|
||||
Generate file
|
||||
Check Private Container
|
||||
Check Public Container
|
||||
Check Read-Only Container
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*** Keywords ***
|
||||
|
||||
Generate Keys
|
||||
${WALLET} = Init wallet
|
||||
Generate wallet ${WALLET}
|
||||
${ADDR} = Dump Address ${WALLET}
|
||||
${USER_KEY_GEN} = Dump PrivKey ${WALLET} ${ADDR}
|
||||
|
||||
${WALLET_OTH} = Init wallet
|
||||
Generate wallet ${WALLET_OTH}
|
||||
${ADDR_OTH} = Dump Address ${WALLET_OTH}
|
||||
${OTHER_KEY_GEN} = Dump PrivKey ${WALLET_OTH} ${ADDR_OTH}
|
||||
|
||||
${SYSTEM_KEY_GEN} = Form WIF from String c428b4a06f166fde9f8afcf918194acdde35aa2612ecf42fe0c94273425ded21
|
||||
${SYSTEM_KEY_GEN_SN} = Form WIF from String 0fa21a94be2227916284e4b3495180d9c93d04f095fe9d5a86f22044f5c411d2
|
||||
|
||||
Set Global Variable ${USER_KEY} ${USER_KEY_GEN}
|
||||
Set Global Variable ${OTHER_KEY} ${OTHER_KEY_GEN}
|
||||
Set Global Variable ${SYSTEM_KEY} ${SYSTEM_KEY_GEN}
|
||||
Set Global Variable ${SYSTEM_KEY_STOR_NODE} ${SYSTEM_KEY_GEN_SN}
|
||||
|
||||
Payment Operations ${WALLET} ${ADDR} ${USER_KEY}
|
||||
Payment Operations ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY}
|
||||
|
||||
# Basic ACL manual page: https://neospcc.atlassian.net/wiki/spaces/NEOF/pages/362348545/NeoFS+ACL
|
||||
# TODO: X - Sticky bit validation on public container!!!
|
||||
|
||||
|
||||
Payment Operations
|
||||
[Arguments] ${WALLET} ${ADDR} ${KEY}
|
||||
|
||||
${TX} = Transfer Mainnet Gas wallets/wallet.json NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx ${ADDR} 55
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 55
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${KEY}
|
||||
|
||||
${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX_DEPOSIT}
|
||||
Get Transaction ${TX_DEPOSIT}
|
||||
|
||||
|
||||
|
||||
|
||||
Create Containers
|
||||
# Create containers:
|
||||
|
||||
|
||||
|
||||
Log Create Private Container
|
||||
${PRIV_CID_GEN} = Create container ${USER_KEY} 0x1C8C8CCC ${RULE_FOR_ALL}
|
||||
Container Existing ${USER_KEY} ${PRIV_CID_GEN}
|
||||
|
||||
Log Create Public Container
|
||||
${PUBLIC_CID_GEN} = Create container ${USER_KEY} 0x1FFFFFFF ${RULE_FOR_ALL}
|
||||
Container Existing ${USER_KEY} ${PUBLIC_CID_GEN}
|
||||
|
||||
Log Create Read-Only Container
|
||||
${READONLY_CID_GEN} = Create container ${USER_KEY} 0x1FFF8CFF ${RULE_FOR_ALL}
|
||||
Container Existing ${USER_KEY} ${READONLY_CID_GEN}
|
||||
|
||||
Set Global Variable ${PRIV_CID} ${PRIV_CID_GEN}
|
||||
Set Global Variable ${PUBLIC_CID} ${PUBLIC_CID_GEN}
|
||||
Set Global Variable ${READONLY_CID} ${READONLY_CID_GEN}
|
||||
|
||||
|
||||
Generate file
|
||||
# Generate small file
|
||||
${FILE_S_GEN} = Generate file of bytes 1024
|
||||
${FILE_S_HASH_GEN} = Get file hash ${FILE_S_GEN}
|
||||
|
||||
Set Global Variable ${FILE_S} ${FILE_S_GEN}
|
||||
Set Global Variable ${FILE_S_HASH} ${FILE_S_HASH_GEN}
|
||||
|
||||
Check Private Container
|
||||
# Check Private:
|
||||
# Expected: User - pass, Other - fail, System(IR) - pass (+ System(Container node) - pass, Non-container node - fail).
|
||||
|
||||
# Put
|
||||
${S_OID_USER} = Put object to NeoFS ${USER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${OTHER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||
# https://github.com/nspcc-dev/neofs-node/issues/178
|
||||
${S_OID_SYS_IR} = Put object to NeoFS ${SYSTEM_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||
${S_OID_SYS_SN} = Put object to NeoFS ${SYSTEM_KEY_STOR_NODE} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||
|
||||
|
||||
|
||||
|
||||
# Get
|
||||
Get object from NeoFS ${USER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${SYSTEM_KEY_STOR_NODE} ${PRIV_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
|
||||
# Get Range Hash
|
||||
Get Range Hash ${USER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Run Keyword And Expect Error *
|
||||
... Get Range Hash ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${SYSTEM_KEY_STOR_NODE} ${PRIV_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
|
||||
# TODO: GetRange https://github.com/nspcc-dev/neofs-node/issues/179
|
||||
|
||||
# Search
|
||||
@{S_OBJ_PRIV} = Create List ${S_OID_USER} ${S_OID_SYS_SN} ${S_OID_SYS_IR}
|
||||
Search object ${USER_KEY} ${PRIV_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Run Keyword And Expect Error *
|
||||
... Search object ${OTHER_KEY} ${PRIV_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${SYSTEM_KEY} ${PRIV_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${SYSTEM_KEY_STOR_NODE} ${PRIV_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
|
||||
|
||||
# Head
|
||||
Head object ${USER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Head object ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY_STOR_NODE} ${PRIV_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
|
||||
|
||||
# Delete
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY_STOR_NODE} ${PRIV_CID} ${S_OID_USER} ${EMPTY}
|
||||
Delete object ${USER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY}
|
||||
|
||||
|
||||
Check Public Container
|
||||
# Check Public:
|
||||
# Expected: User - pass, Other - fail, System(IR) - pass (+ System(Container node) - pass, Non-container node - fail).
|
||||
|
||||
# Put
|
||||
# By discussion, IR can not make any operations instead of HEAD, SEARCH and GET RANGE HASH at the current moment ???
|
||||
${S_OID_USER} = Put object to NeoFS ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
||||
${S_OID_OTHER} = Put object to NeoFS ${OTHER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
||||
# https://github.com/nspcc-dev/neofs-node/issues/178
|
||||
${S_OID_SYS_IR} = Put object to NeoFS ${SYSTEM_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
||||
${S_OID_SYS_SN} = Put object to NeoFS ${SYSTEM_KEY_STOR_NODE} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
||||
|
||||
# Get
|
||||
Get object from NeoFS ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
|
||||
# Get Range Hash
|
||||
Get Range Hash ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
|
||||
# Search
|
||||
@{S_OBJ_PRIV} = Create List ${S_OID_USER} ${S_OID_OTHER} ${S_OID_SYS_SN} ${S_OID_SYS_IR}
|
||||
Search object ${USER_KEY} ${PUBLIC_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${OTHER_KEY} ${PUBLIC_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${SYSTEM_KEY} ${PUBLIC_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_PRIV}
|
||||
|
||||
# Head
|
||||
Head object ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
|
||||
Head object ${USER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY}
|
||||
Head object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY}
|
||||
|
||||
Head object ${USER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} ${EMPTY}
|
||||
Head object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} ${EMPTY}
|
||||
|
||||
|
||||
# Delete
|
||||
# https://github.com/nspcc-dev/neofs-node/issues/178
|
||||
Delete object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY}
|
||||
Delete object ${SYSTEM_KEY_STOR_NODE} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY}
|
||||
Delete object ${USER_KEY} ${PUBLIC_CID} ${S_OID_SYS_IR} ${EMPTY}
|
||||
Delete object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY}
|
||||
|
||||
|
||||
Check Read-Only Container
|
||||
# Check Read Only container:
|
||||
|
||||
# Put
|
||||
${S_OID_USER} = Put object to NeoFS ${USER_KEY} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${OTHER_KEY} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
||||
${S_OID_SYS_IR} = Put object to NeoFS ${SYSTEM_KEY} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
||||
${S_OID_SYS_SN} = Put object to NeoFS ${SYSTEM_KEY_STOR_NODE} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
||||
|
||||
# Get
|
||||
Get object from NeoFS ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${SYSTEM_KEY_STOR_NODE} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||
|
||||
# Get Range Hash
|
||||
Get Range Hash ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
Get Range Hash ${SYSTEM_KEY_STOR_NODE} ${READONLY_CID} ${S_OID_USER} ${EMPTY} 0:256
|
||||
|
||||
# Search
|
||||
@{S_OBJ_RO} = Create List ${S_OID_USER} ${S_OID_SYS_SN} ${S_OID_SYS_IR}
|
||||
Search object ${USER_KEY} ${READONLY_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_RO}
|
||||
Search object ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_RO}
|
||||
Search object ${SYSTEM_KEY} ${READONLY_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_RO}
|
||||
Search object ${SYSTEM_KEY_STOR_NODE} ${READONLY_CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_RO}
|
||||
|
||||
|
||||
# Head
|
||||
Head object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
Head object ${SYSTEM_KEY_STOR_NODE} ${READONLY_CID} ${S_OID_USER} ${EMPTY} ${EMPTY}
|
||||
|
||||
# Delete
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY_STOR_NODE} ${READONLY_CID} ${S_OID_USER} ${EMPTY}
|
||||
Delete object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY}
|
104
robot/testsuites/integration/object_complex_api2.robot
Normal file
104
robot/testsuites/integration/object_complex_api2.robot
Normal file
|
@ -0,0 +1,104 @@
|
|||
*** Settings ***
|
||||
Variables ../../variables/common.py
|
||||
|
||||
Library ${RESOURCES}/environment.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
Library ${RESOURCES}/neofs.py
|
||||
Library ${RESOURCES}/payment_neogo.py
|
||||
Library ${RESOURCES}/assertions.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
|
||||
*** Variables ***
|
||||
${FILE_USR_HEADER} = key1=1,key2=abc
|
||||
|
||||
|
||||
*** Test cases ***
|
||||
NeoFS Simple Object Operations
|
||||
[Documentation] Testcase to validate NeoFS operations with simple object.
|
||||
[Tags] Object NeoFS NeoCLI
|
||||
[Timeout] 20 min
|
||||
|
||||
${WALLET} = Init wallet
|
||||
Generate wallet ${WALLET}
|
||||
${ADDR} = Dump Address ${WALLET}
|
||||
${PRIV_KEY} = Dump PrivKey ${WALLET} ${ADDR}
|
||||
${TX} = Transfer Mainnet Gas wallets/wallet.json NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx ${ADDR} 55
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 55
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX_DEPOSIT}
|
||||
Get Transaction ${TX_DEPOSIT}
|
||||
|
||||
${BALANCE} = Wait Until Keyword Succeeds 5 min 1 min
|
||||
... Expected Balance ${PRIV_KEY} 0 50
|
||||
|
||||
${CID} = Create container ${PRIV_KEY}
|
||||
Container Existing ${PRIV_KEY} ${CID}
|
||||
|
||||
Wait Until Keyword Succeeds 2 min 30 sec
|
||||
... Expected Balance ${PRIV_KEY} 50 -0.0007
|
||||
|
||||
${SIZE} = Set Variable 20e+6
|
||||
${FILE} = Generate file of bytes ${SIZE}
|
||||
${FILE_HASH} = Get file hash ${FILE}
|
||||
|
||||
|
||||
${S_OID} = Put object to NeoFS ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${EMPTY}
|
||||
${H_OID} = Put object to NeoFS ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
||||
|
||||
Validate storage policy for object ${PRIV_KEY} 2 ${CID} ${S_OID}
|
||||
Validate storage policy for object ${PRIV_KEY} 2 ${CID} ${H_OID}
|
||||
|
||||
|
||||
# @{Link_obj_S} = Verify linked objects ${PRIV_KEY} ${CID} ${S_OID} ${SIZE}
|
||||
# @{Link_obj_H} = Verify linked objects ${PRIV_KEY} ${CID} ${H_OID} ${SIZE}
|
||||
# @{Full_obj_list} = Create List @{Link_obj_S} @{Link_obj_H} ${S_OID} ${H_OID}
|
||||
# Search object ${PRIV_KEY} ${CID} ${EMPTY} ${EMPTY} @{Full_obj_list}
|
||||
|
||||
Run Keyword And Expect Error *
|
||||
... Search object ${PRIV_KEY} ${CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_ALL}
|
||||
|
||||
|
||||
|
||||
|
||||
@{S_OBJ_ALL} = Create List ${S_OID} ${H_OID}
|
||||
@{S_OBJ_H} = Create List ${H_OID}
|
||||
|
||||
Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} h_file_read
|
||||
|
||||
Verify file hash s_file_read ${FILE_HASH}
|
||||
Verify file hash h_file_read ${FILE_HASH}
|
||||
|
||||
Search object ${PRIV_KEY} ${CID} --root ${EMPTY} ${EMPTY} @{S_OBJ_ALL}
|
||||
Search object ${PRIV_KEY} ${CID} --root ${EMPTY} ${FILE_USR_HEADER} @{S_OBJ_H}
|
||||
|
||||
Head object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY}
|
||||
Head object ${PRIV_KEY} ${CID} ${H_OID} ${EMPTY} ${FILE_USR_HEADER}
|
||||
|
||||
Delete object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY}
|
||||
Delete object ${PRIV_KEY} ${CID} ${H_OID} ${EMPTY}
|
||||
#Verify Head tombstone ${PRIV_KEY} ${CID} ${S_OID}
|
||||
|
||||
Sleep 2min
|
||||
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${PRIV_KEY} ${CID} ${H_OID} ${EMPTY} h_file_read
|
||||
|
||||
Cleanup File ${FILE}
|
||||
Cleanup File s_file_read
|
||||
Cleanup File h_file_read
|
||||
|
||||
# 4.86192020
|
||||
|
||||
|
||||
|
||||
|
92
robot/testsuites/integration/object_simple_api2.robot
Normal file
92
robot/testsuites/integration/object_simple_api2.robot
Normal file
|
@ -0,0 +1,92 @@
|
|||
*** Settings ***
|
||||
Variables ../../variables/common.py
|
||||
|
||||
Library ${RESOURCES}/environment.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
Library ${RESOURCES}/neofs.py
|
||||
Library ${RESOURCES}/payment_neogo.py
|
||||
Library ${RESOURCES}/assertions.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
|
||||
*** Variables ***
|
||||
${FILE_USR_HEADER} = key1=1,key2=abc
|
||||
|
||||
|
||||
*** Test cases ***
|
||||
NeoFS Simple Object Operations
|
||||
[Documentation] Testcase to validate NeoFS operations with simple object.
|
||||
[Tags] Object NeoFS NeoCLI
|
||||
[Timeout] 20 min
|
||||
|
||||
${WALLET} = Init wallet
|
||||
Generate wallet ${WALLET}
|
||||
${ADDR} = Dump Address ${WALLET}
|
||||
${PRIV_KEY} = Dump PrivKey ${WALLET} ${ADDR}
|
||||
${TX} = Transfer Mainnet Gas wallets/wallet.json NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx ${ADDR} 55
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 55
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX_DEPOSIT}
|
||||
Get Transaction ${TX_DEPOSIT}
|
||||
|
||||
${BALANCE} = Wait Until Keyword Succeeds 5 min 1 min
|
||||
... Expected Balance ${PRIV_KEY} 0 50
|
||||
|
||||
${CID} = Create container ${PRIV_KEY}
|
||||
Container Existing ${PRIV_KEY} ${CID}
|
||||
|
||||
Wait Until Keyword Succeeds 2 min 30 sec
|
||||
... Expected Balance ${PRIV_KEY} 50 -0.0007
|
||||
|
||||
${FILE} = Generate file of bytes 1024
|
||||
${FILE_HASH} = Get file hash ${FILE}
|
||||
|
||||
|
||||
${S_OID} = Put object to NeoFS ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${EMPTY}
|
||||
${H_OID} = Put object to NeoFS ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
||||
|
||||
Validate storage policy for object ${PRIV_KEY} 2 ${CID} ${S_OID}
|
||||
Validate storage policy for object ${PRIV_KEY} 2 ${CID} ${H_OID}
|
||||
|
||||
@{S_OBJ_ALL} = Create List ${S_OID} ${H_OID}
|
||||
@{S_OBJ_H} = Create List ${H_OID}
|
||||
|
||||
Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read
|
||||
Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} h_file_read
|
||||
|
||||
Verify file hash s_file_read ${FILE_HASH}
|
||||
Verify file hash h_file_read ${FILE_HASH}
|
||||
|
||||
Search object ${PRIV_KEY} ${CID} ${EMPTY} ${EMPTY} ${EMPTY} @{S_OBJ_ALL}
|
||||
Search object ${PRIV_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} @{S_OBJ_H}
|
||||
|
||||
Head object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY}
|
||||
Head object ${PRIV_KEY} ${CID} ${H_OID} ${EMPTY} ${FILE_USR_HEADER}
|
||||
|
||||
Delete object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY}
|
||||
Delete object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY}
|
||||
#Verify Head tombstone ${PRIV_KEY} ${CID} ${S_OID}
|
||||
|
||||
Sleep 2min
|
||||
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read
|
||||
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${PRIV_KEY} ${CID} ${H_OID} ${EMPTY} h_file_read
|
||||
|
||||
Cleanup File ${FILE}
|
||||
Cleanup File s_file_read
|
||||
Cleanup File h_file_read
|
||||
|
||||
# 4.86192020
|
||||
|
||||
|
||||
|
||||
|
235
robot/testsuites/integration/tmp/acl_basic_fix_check.robot
Normal file
235
robot/testsuites/integration/tmp/acl_basic_fix_check.robot
Normal file
|
@ -0,0 +1,235 @@
|
|||
*** Settings ***
|
||||
Variables ../../variables/common.py
|
||||
|
||||
|
||||
Library ${RESOURCES}/environment.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
Library ${RESOURCES}/neofs.py
|
||||
Library ${RESOURCES}/payment.py
|
||||
Library ${RESOURCES}/assertions.py
|
||||
Library ${RESOURCES}/neo.py
|
||||
|
||||
|
||||
|
||||
*** Variables ***
|
||||
&{FILE_USR_HEADER} = key1=1 key2='abc'
|
||||
|
||||
|
||||
*** Test cases ***
|
||||
Basic ACL Operations
|
||||
[Documentation] Testcase to validate NeoFS operations with ACL.
|
||||
[Tags] ACL NeoFS NeoCLI
|
||||
[Timeout] 20 min
|
||||
|
||||
# Set private keys for User, Other, System
|
||||
# Set private keys for each storage node
|
||||
${USER_KEY} = Generate Neo private key
|
||||
${OTHER_KEY} = Generate Neo private key
|
||||
${SYSTEM_KEY} = Form Privkey from String c428b4a06f166fde9f8afcf918194acdde35aa2612ecf42fe0c94273425ded21
|
||||
|
||||
# Set private keys for each storage node
|
||||
${NODE1_KEY} = Form Privkey from String 0fa21a94be2227916284e4b3495180d9c93d04f095fe9d5a86f22044f5c411d2
|
||||
${NODE2_KEY} = Form Privkey from String 7befa3cd57bae15420db19fb3639db73f1683412a28271bc413129f286a0f8aa
|
||||
${NODE3_KEY} = Form Privkey from String 5dcbb7901b3a377f17e1b43542091affe1291846a4c9365ab21f6b01c72b887d
|
||||
${NODE4_KEY} = Form Privkey from String 691970fbb57476ec85f5777d948de91cf3f121688281259feb202f49f4d8e861
|
||||
|
||||
# Basic ACL manual page: https://neospcc.atlassian.net/wiki/spaces/NEOF/pages/362348545/NeoFS+ACL
|
||||
|
||||
# TODO: X - Sticky bit validation on public container!!!
|
||||
|
||||
|
||||
# Create containers:
|
||||
${PUB_KEY} = Get Neo public key ${USER_KEY}
|
||||
${ADDR} = Get Neo address ${USER_KEY}
|
||||
|
||||
Log Create Private Container
|
||||
${PRIV_CID} = Create container ${USER_KEY} 0x1C8C8CCC
|
||||
Container Existing ${USER_KEY} ${PRIV_CID}
|
||||
|
||||
Log Create Public Container
|
||||
${PUBLIC_CID} = Create container ${USER_KEY} 0x3FFFFFFF
|
||||
Container Existing ${USER_KEY} ${PUBLIC_CID}
|
||||
|
||||
Log Create Read-Only Container
|
||||
${READONLY_CID} = Create container ${USER_KEY} 0x1FFFCCFF
|
||||
Container Existing ${USER_KEY} ${READONLY_CID}
|
||||
|
||||
|
||||
# Generate small file
|
||||
${FILE_S} = Generate file of bytes 1024
|
||||
${FILE_S_HASH} = Get file hash ${FILE_S}
|
||||
|
||||
# Check Private:
|
||||
# Expected: User - pass, Other - fail, System(IR) - pass (+ System(Container node) - pass, Non-container node - fail).
|
||||
|
||||
# Put
|
||||
${S_OID_USER} = Put object to NeoFS ${USER_KEY} ${FILE_S} ${PRIV_CID}
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${OTHER_KEY} ${FILE_S} ${PRIV_CID}
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${SYSTEM_KEY} ${FILE_S} ${PRIV_CID}
|
||||
|
||||
|
||||
# Get
|
||||
Get object from NeoFS ${USER_KEY} ${PRIV_CID} ${S_OID_USER} s_file_read
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER} s_file_read
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER} s_file_read
|
||||
|
||||
# Get Range
|
||||
Get Range ${USER_KEY} ${PRIV_CID} ${S_OID_USER} 0:256
|
||||
Run Keyword And Expect Error *
|
||||
... Get Range ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER} 0:256
|
||||
Run Keyword And Expect Error *
|
||||
... Get Range ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER} 0:256
|
||||
|
||||
# TODO: GetRangeHash
|
||||
# get-range-hash --cid <cid> --oid <oid> [--bearer <hex>] [--verify --file </path/to/file>] [--salt <hex>] [<offset1>:<length1> [...]]
|
||||
# neospcc@neospcc:~/GIT/neofs-testcases$ docker exec neofs-cli neofs-cli --host 192.168.123.71:8080 --key 0fa21a94be2227916284e4b3495180d9c93d04f095fe9d5a86f22044f5c411d2 object get-range-hash --cid 4H9iChvzYdBg6qntfYUWGWCzsJFBDdo99KegefsD721Q --oid a101d078-b3d4-4325-8fe8-41dce6917097
|
||||
# invalid input
|
||||
# Usage: get-range-hash --cid <cid> --oid <oid> [--bearer <hex>] [--verify --file </path/to/file>] [--salt <hex>] [<offset1>:<length1> [...]]
|
||||
|
||||
|
||||
# Search
|
||||
@{S_OBJ_PRIV} = Create List ${S_OID_USER}
|
||||
Search object ${USER_KEY} ${PRIV_CID} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Run Keyword And Expect Error *
|
||||
... Search object ${OTHER_KEY} ${PRIV_CID} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${SYSTEM_KEY} ${PRIV_CID} ${EMPTY} @{S_OBJ_PRIV}
|
||||
|
||||
|
||||
# Head
|
||||
Head object ${USER_KEY} ${PRIV_CID} ${S_OBJ_PRIV} ${True}
|
||||
Run Keyword And Expect Error *
|
||||
... Head object ${OTHER_KEY} ${PRIV_CID} ${S_OBJ_PRIV} ${True}
|
||||
Head object ${SYSTEM_KEY} ${PRIV_CID} ${S_OBJ_PRIV} ${True}
|
||||
|
||||
|
||||
# Delete
|
||||
Delete object ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${OTHER_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Check Public:
|
||||
# Expected: User - pass, Other - fail, System(IR) - pass (+ System(Container node) - pass, Non-container node - fail).
|
||||
|
||||
# Put
|
||||
${S_OID_USER} = Put object to NeoFS ${USER_KEY} ${FILE_S} ${PUBLIC_CID}
|
||||
${S_OID_OTHER} = Put object to NeoFS ${OTHER_KEY} ${FILE_S} ${PUBLIC_CID}
|
||||
# By discussion, IR can not make any operations instead of HEAD, SEARCH and GET RANGE HASH at the current moment
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${SYSTEM_KEY} ${FILE_S} ${PUBLIC_CID}
|
||||
|
||||
# Get
|
||||
Get object from NeoFS ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} s_file_read
|
||||
Get object from NeoFS ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} s_file_read
|
||||
# By discussion, IR can not make any operations instead of HEAD, SEARCH and GET RANGE HASH at the current moment
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} s_file_read
|
||||
|
||||
# Get Range
|
||||
Get Range ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} 0:256
|
||||
Get Range ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} 0:256
|
||||
# By discussion, IR can not make any operations instead of HEAD, SEARCH and GET RANGE HASH at the current moment
|
||||
Run Keyword And Expect Error *
|
||||
... Get Range ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} 0:256
|
||||
|
||||
# TODO: GetRangeHash
|
||||
# get-range-hash --cid <cid> --oid <oid> [--bearer <hex>] [--verify --file </path/to/file>] [--salt <hex>] [<offset1>:<length1> [...]]
|
||||
# neospcc@neospcc:~/GIT/neofs-testcases$ docker exec neofs-cli neofs-cli --host 192.168.123.71:8080 --key 0fa21a94be2227916284e4b3495180d9c93d04f095fe9d5a86f22044f5c411d2 object get-range-hash --cid 4H9iChvzYdBg6qntfYUWGWCzsJFBDdo99KegefsD721Q --oid a101d078-b3d4-4325-8fe8-41dce6917097
|
||||
# invalid input
|
||||
# Usage: get-range-hash --cid <cid> --oid <oid> [--bearer <hex>] [--verify --file </path/to/file>] [--salt <hex>] [<offset1>:<length1> [...]]
|
||||
|
||||
|
||||
# Search
|
||||
@{S_OBJ_PRIV} = Create List ${S_OID_USER} ${S_OID_OTHER}
|
||||
Search object ${USER_KEY} ${PUBLIC_CID} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${OTHER_KEY} ${PUBLIC_CID} ${EMPTY} @{S_OBJ_PRIV}
|
||||
Search object ${SYSTEM_KEY} ${PUBLIC_CID} ${EMPTY} @{S_OBJ_PRIV}
|
||||
|
||||
|
||||
# Head
|
||||
Head object ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${True}
|
||||
Head object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${True}
|
||||
Head object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER} ${True}
|
||||
|
||||
Head object ${USER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${True}
|
||||
Head object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${True}
|
||||
Head object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${True}
|
||||
|
||||
# Delete
|
||||
Delete object ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER}
|
||||
Delete object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY} ${PUBLIC_CID} ${S_OID_USER}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Check Read Only container:
|
||||
|
||||
# Put
|
||||
${S_OID_USER} = Put object to NeoFS ${USER_KEY} ${FILE_S} ${READONLY_CID}
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${OTHER_KEY} ${FILE_S} ${READONLY_CID}
|
||||
Run Keyword And Expect Error *
|
||||
... Put object to NeoFS ${SYSTEM_KEY} ${FILE_S} ${READONLY_CID}
|
||||
|
||||
# Get
|
||||
Get object from NeoFS ${USER_KEY} ${READONLY_CID} ${S_OID_USER} s_file_read
|
||||
Get object from NeoFS ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} s_file_read
|
||||
# By discussion, IR can not make any operations instead of HEAD, SEARCH and GET RANGE HASH at the current moment
|
||||
Run Keyword And Expect Error *
|
||||
... Get object from NeoFS ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} s_file_read
|
||||
|
||||
# Get Range
|
||||
Get Range ${USER_KEY} ${READONLY_CID} ${S_OID_USER} 0:256
|
||||
Get Range ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} 0:256
|
||||
# By discussion, IR can not make any operations instead of HEAD, SEARCH and GET RANGE HASH at the current moment
|
||||
Run Keyword And Expect Error *
|
||||
... Get Range ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} 0:256
|
||||
|
||||
# TODO: GetRangeHash
|
||||
# get-range-hash --cid <cid> --oid <oid> [--bearer <hex>] [--verify --file </path/to/file>] [--salt <hex>] [<offset1>:<length1> [...]]
|
||||
# neospcc@neospcc:~/GIT/neofs-testcases$ docker exec neofs-cli neofs-cli --host 192.168.123.71:8080 --key 0fa21a94be2227916284e4b3495180d9c93d04f095fe9d5a86f22044f5c411d2 object get-range-hash --cid 4H9iChvzYdBg6qntfYUWGWCzsJFBDdo99KegefsD721Q --oid a101d078-b3d4-4325-8fe8-41dce6917097
|
||||
# invalid input
|
||||
# Usage: get-range-hash --cid <cid> --oid <oid> [--bearer <hex>] [--verify --file </path/to/file>] [--salt <hex>] [<offset1>:<length1> [...]]
|
||||
|
||||
|
||||
# Search
|
||||
@{S_OBJ_RO} = Create List ${S_OID_USER}
|
||||
Search object ${USER_KEY} ${READONLY_CID} ${EMPTY} @{S_OBJ_RO}
|
||||
Search object ${OTHER_KEY} ${READONLY_CID} ${EMPTY} @{S_OBJ_RO}
|
||||
Search object ${SYSTEM_KEY} ${READONLY_CID} ${EMPTY} @{S_OBJ_RO}
|
||||
|
||||
|
||||
# Head
|
||||
Head object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${True}
|
||||
Head object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${True}
|
||||
Head object ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER} ${True}
|
||||
|
||||
# Delete
|
||||
Delete object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||
Run Keyword And Expect Error *
|
||||
... Delete object ${SYSTEM_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue