forked from TrueCloudLab/frostfs-testcases
[#127]: Large Object assrtions moved from python to robot
Signed-off-by: anastasia prasolova <anastasia@nspcc.ru>
This commit is contained in:
parent
040f648c61
commit
15dd59ddad
12 changed files with 240 additions and 218 deletions
74
robot/resources/lib/python/complex_object_actions.py
Normal file
74
robot/resources/lib/python/complex_object_actions.py
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
This module contains functions which are used for Large Object assemling:
|
||||||
|
getting Last Object and split and getting Link Object. It is not enough to
|
||||||
|
simply perform a "raw" HEAD request, as noted in the issue:
|
||||||
|
https://github.com/nspcc-dev/neofs-node/issues/1304. Therefore, the reliable
|
||||||
|
retrival of the aforementioned objects must be done this way: send direct
|
||||||
|
"raw" HEAD request to the every Storage Node and return the desired OID on
|
||||||
|
first non-null response.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from common import NEOFS_NETMAP
|
||||||
|
import neofs_verbs
|
||||||
|
|
||||||
|
from robot.api.deco import keyword
|
||||||
|
from robot.api import logger
|
||||||
|
from robot.libraries.BuiltIn import BuiltIn
|
||||||
|
|
||||||
|
ROBOT_AUTO_KEYWORDS = False
|
||||||
|
|
||||||
|
|
||||||
|
@keyword('Get Link Object')
|
||||||
|
def get_link_object(wallet: str, cid: str, oid: str):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
wallet (str): path to the wallet on whose behalf the Storage Nodes
|
||||||
|
are requested
|
||||||
|
cid (str): Container ID which stores the Large Object
|
||||||
|
oid (str): Large Object ID
|
||||||
|
Returns:
|
||||||
|
(str): Link Object ID
|
||||||
|
When no Link Object ID is found after all Storage Nodes polling,
|
||||||
|
the function throws a native robot error.
|
||||||
|
"""
|
||||||
|
for node in NEOFS_NETMAP:
|
||||||
|
try:
|
||||||
|
resp = neofs_verbs.head_object(wallet, cid, oid,
|
||||||
|
endpoint=node,
|
||||||
|
is_raw=True,
|
||||||
|
is_direct=True)
|
||||||
|
if resp['link']:
|
||||||
|
return resp['link']
|
||||||
|
except Exception:
|
||||||
|
logger.info(f"No Link Object found on {node}; continue")
|
||||||
|
BuiltIn().fail(f"No Link Object for {cid}/{oid} found among all Storage Nodes")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@keyword('Get Last Object')
|
||||||
|
def get_last_object(wallet: str, cid: str, oid: str):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
wallet (str): path to the wallet on whose behalf the Storage Nodes
|
||||||
|
are requested
|
||||||
|
cid (str): Container ID which stores the Large Object
|
||||||
|
oid (str): Large Object ID
|
||||||
|
Returns:
|
||||||
|
(str): Last Object ID
|
||||||
|
When no Last Object ID is found after all Storage Nodes polling,
|
||||||
|
the function throws a native robot error.
|
||||||
|
"""
|
||||||
|
for node in NEOFS_NETMAP:
|
||||||
|
try:
|
||||||
|
resp = neofs_verbs.head_object(wallet, cid, oid,
|
||||||
|
endpoint=node,
|
||||||
|
is_raw=True,
|
||||||
|
is_direct=True)
|
||||||
|
if resp['lastPart']:
|
||||||
|
return resp['lastPart']
|
||||||
|
except Exception:
|
||||||
|
logger.info(f"No Last Object found on {node}; continue")
|
||||||
|
BuiltIn().fail(f"No Last Object for {cid}/{oid} found among all Storage Nodes")
|
||||||
|
return None
|
|
@ -174,183 +174,6 @@ def container_existing(private_key: str, cid: str):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@keyword('Get Split objects')
|
|
||||||
def get_component_objects(private_key: str, cid: str, oid: str):
|
|
||||||
logger.info("Collect Split objects list from Linked object.")
|
|
||||||
split_id = ""
|
|
||||||
for node in NEOFS_NETMAP:
|
|
||||||
try:
|
|
||||||
parsed_header_virtual = neofs_verbs.head_object(private_key, cid, oid, options=' --ttl 1',
|
|
||||||
endpoint=node, is_raw=True)
|
|
||||||
|
|
||||||
if 'link' in parsed_header_virtual.keys():
|
|
||||||
return _collect_split_objects_from_header(private_key, cid, parsed_header_virtual)
|
|
||||||
|
|
||||||
elif 'split' in parsed_header_virtual['header'].keys():
|
|
||||||
logger.info(f"parsed_header_virtual: !@ {parsed_header_virtual}" )
|
|
||||||
split_id = parsed_header_virtual['header']['splitID']
|
|
||||||
|
|
||||||
except:
|
|
||||||
logger.warn("Linking object has not been found.")
|
|
||||||
|
|
||||||
# Get all existing objects
|
|
||||||
full_obj_list = neofs_verbs.search_object(private_key, cid, None, None, None, None, '--phy')
|
|
||||||
|
|
||||||
# Search expected Linking object
|
|
||||||
for targer_oid in full_obj_list:
|
|
||||||
header_parsed = neofs_verbs.head_object(private_key, cid, targer_oid, is_raw=True)
|
|
||||||
if header_parsed['header']['split']:
|
|
||||||
if header_parsed['header']['split']['splitID'] == split_id and 'children' in header_parsed['header']['split'].keys():
|
|
||||||
logger.info("Linking object has been found in additional check (head of all objects).")
|
|
||||||
return _collect_split_objects_from_header(private_key, cid, parsed_header_virtual)
|
|
||||||
|
|
||||||
|
|
||||||
raise Exception("Linking object is not found at all - all existed objects have been headed.")
|
|
||||||
|
|
||||||
def _collect_split_objects_from_header(private_key, cid, parsed_header):
|
|
||||||
header_link_parsed = neofs_verbs.head_object(private_key, cid, parsed_header['link'])
|
|
||||||
return header_link_parsed['header']['split']['children']
|
|
||||||
|
|
||||||
|
|
||||||
@keyword('Verify Split Chain')
|
|
||||||
def verify_split_chain(wif: str, cid: str, oid: str):
|
|
||||||
|
|
||||||
header_virtual_parsed = dict()
|
|
||||||
header_last_parsed = dict()
|
|
||||||
|
|
||||||
marker_last_obj = 0
|
|
||||||
marker_link_obj = 0
|
|
||||||
|
|
||||||
final_verif_data = dict()
|
|
||||||
|
|
||||||
# Get Latest object
|
|
||||||
logger.info("Collect Split objects information and verify chain of the objects.")
|
|
||||||
for node in NEOFS_NETMAP:
|
|
||||||
try:
|
|
||||||
parsed_header_virtual = neofs_verbs.head_object(wif, cid, oid, options=' --ttl 1',
|
|
||||||
endpoint=node, is_raw=True)
|
|
||||||
logger.info(f"header {parsed_header_virtual}")
|
|
||||||
|
|
||||||
if 'lastPart' in parsed_header_virtual.keys():
|
|
||||||
header_last_parsed = neofs_verbs.head_object(wif, cid,
|
|
||||||
parsed_header_virtual['lastPart'],
|
|
||||||
is_raw=True)
|
|
||||||
marker_last_obj = 1
|
|
||||||
|
|
||||||
# Recursive chain validation up to the first object
|
|
||||||
final_verif_data = _verify_child_link(wif, cid, oid, header_last_parsed['header'], final_verif_data)
|
|
||||||
break
|
|
||||||
logger.info(f"Found Split Object with header:\n\t{parsed_header_virtual}")
|
|
||||||
logger.info("Continue to search Last Split Object")
|
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
logger.info(f"Failed while collectiong Split Objects: {exc}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if marker_last_obj == 0:
|
|
||||||
raise Exception("Last object has not been found")
|
|
||||||
|
|
||||||
# Get Linking object
|
|
||||||
logger.info("Compare Split objects result information with Linking object.")
|
|
||||||
for node in NEOFS_NETMAP:
|
|
||||||
try:
|
|
||||||
parsed_header_virtual = neofs_verbs.head_object(wif, cid, oid, options=' --ttl 1',
|
|
||||||
endpoint=node, is_raw=True)
|
|
||||||
if 'link' in parsed_header_virtual.keys():
|
|
||||||
header_link_parsed = neofs_verbs.head_object(wif, cid,
|
|
||||||
parsed_header_virtual['link'],
|
|
||||||
is_raw=True)
|
|
||||||
marker_link_obj = 1
|
|
||||||
|
|
||||||
reversed_list = final_verif_data['header']['split']['children'][::-1]
|
|
||||||
|
|
||||||
if header_link_parsed['header']['split']['children'] == reversed_list:
|
|
||||||
logger.info(f"Split objects list from Linked Object is equal to expected "
|
|
||||||
f"{', '.join(header_link_parsed['header']['split']['children'])}")
|
|
||||||
else:
|
|
||||||
raise Exception(f"Split objects list from Linking Object "
|
|
||||||
f"({', '.join(header_link_parsed['header']['split']['children'])}) "
|
|
||||||
f"is not equal to expected ({', '.join(reversed_list)})")
|
|
||||||
|
|
||||||
if int(header_link_parsed['header']['payloadLength']) == 0:
|
|
||||||
logger.info("Linking object Payload is equal to expected - zero size.")
|
|
||||||
else:
|
|
||||||
raise Exception("Linking object Payload is not equal to expected. Should be zero.")
|
|
||||||
|
|
||||||
if header_link_parsed['header']['objectType'] == 'REGULAR':
|
|
||||||
logger.info("Linking Object Type is 'regular' as expected.")
|
|
||||||
else:
|
|
||||||
raise Exception("Object Type is not 'regular'.")
|
|
||||||
|
|
||||||
if header_link_parsed['header']['split']['children'] == final_verif_data['split']['children']:
|
|
||||||
logger.info(f"Linking Object Split ID is equal to expected {final_verif_data['split']['children']}.")
|
|
||||||
else:
|
|
||||||
raise Exception(f"Split ID from Linking Object ({header_link_parsed['header']['split']['children']}) "
|
|
||||||
f"is not equal to expected ({final_verif_data['split']['children']})")
|
|
||||||
|
|
||||||
break
|
|
||||||
logger.info(f"Found Linking Object with header:\n\t{parsed_header_virtual}")
|
|
||||||
logger.info("Continue to search Linking Object")
|
|
||||||
except RuntimeError as e:
|
|
||||||
logger.info(f"Failed while collecting Split Object: {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if marker_link_obj == 0:
|
|
||||||
raise Exception("Linked object has not been found")
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("Compare Split objects result information with Virtual object.")
|
|
||||||
|
|
||||||
header_virtual_parsed = neofs_verbs.head_object(wif, cid, oid)
|
|
||||||
|
|
||||||
if int(header_virtual_parsed['header']['payloadLength']) == int(final_verif_data['payloadLength']):
|
|
||||||
logger.info(f"Split objects PayloadLength are equal to Virtual Object Payload "
|
|
||||||
f"{header_virtual_parsed['header']['payloadLength']}")
|
|
||||||
else:
|
|
||||||
raise Exception(f"Split objects PayloadLength from Virtual Object "
|
|
||||||
f"({header_virtual_parsed['header']['payloadLength']}) is not equal "
|
|
||||||
f"to expected ({final_verif_data['payloadLength']})")
|
|
||||||
|
|
||||||
if header_link_parsed['header']['objectType'] == 'REGULAR':
|
|
||||||
logger.info("Virtual Object Type is 'regular' as expected.")
|
|
||||||
else:
|
|
||||||
raise Exception("Object Type is not 'regular'.")
|
|
||||||
|
|
||||||
|
|
||||||
def _verify_child_link(wif: str, cid: str, oid: str, header_last_parsed: dict, final_verif_data: dict):
|
|
||||||
|
|
||||||
if 'payloadLength' in final_verif_data.keys():
|
|
||||||
final_verif_data['payloadLength'] = int(final_verif_data['payloadLength']) + int(header_last_parsed['payloadLength'])
|
|
||||||
else:
|
|
||||||
final_verif_data['payloadLength'] = int(header_last_parsed['payloadLength'])
|
|
||||||
|
|
||||||
if header_last_parsed['objectType'] != 'REGULAR':
|
|
||||||
raise Exception("Object Type is not 'regular'.")
|
|
||||||
|
|
||||||
if 'split' in final_verif_data.keys():
|
|
||||||
if final_verif_data['split']['splitID'] != header_last_parsed['split']['splitID']:
|
|
||||||
raise Exception(f"Object Split ID ({header_last_parsed['split']['splitID']}) "
|
|
||||||
f"is not expected ({final_verif_data['split']['splitID']}).")
|
|
||||||
else:
|
|
||||||
final_verif_data['split']['splitID'] = header_last_parsed['split']['splitID']
|
|
||||||
|
|
||||||
if 'children' in final_verif_data['split'].keys():
|
|
||||||
final_verif_data['split']['children'].append(header_last_parsed['split']['children'])
|
|
||||||
else:
|
|
||||||
final_verif_data['split']['children'] = []
|
|
||||||
final_verif_data['split']['children'].append(header_last_parsed['split']['children'])
|
|
||||||
|
|
||||||
if 'previous' in header_last_parsed['split'].keys():
|
|
||||||
parsed_header_virtual = neofs_verbs.head_object(wif, cid, header_last_parsed['split']['previous'], is_raw=True)
|
|
||||||
|
|
||||||
final_verif_data = _verify_child_link(wif, cid, oid, parsed_header_virtual, final_verif_data)
|
|
||||||
else:
|
|
||||||
logger.info("Chain of the objects has been parsed from the last object ot the first.")
|
|
||||||
|
|
||||||
return final_verif_data
|
|
||||||
|
|
||||||
|
|
||||||
@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):
|
||||||
# TODO: replace with HEAD from neofs_verbs.py
|
# TODO: replace with HEAD from neofs_verbs.py
|
||||||
|
@ -540,9 +363,6 @@ def find_in_nodes_Log(line: str, nodes_logs_time: dict):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@keyword('Put Storagegroup')
|
@keyword('Put Storagegroup')
|
||||||
def put_storagegroup(private_key: str, cid: str, bearer_token: str="", *oid_list):
|
def put_storagegroup(private_key: str, cid: str, bearer_token: str="", *oid_list):
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ def search_object(wif: str, cid: str, keys: str="", bearer: str="", filters: dic
|
||||||
@keyword('Head object')
|
@keyword('Head object')
|
||||||
def head_object(wif: str, cid: str, oid: str, bearer_token: str="",
|
def head_object(wif: str, cid: str, oid: str, bearer_token: str="",
|
||||||
options:str="", endpoint: str="", json_output: bool = True,
|
options:str="", endpoint: str="", json_output: bool = True,
|
||||||
is_raw: bool = False):
|
is_raw: bool = False, is_direct: bool = False):
|
||||||
'''
|
'''
|
||||||
HEAD an Object.
|
HEAD an Object.
|
||||||
|
|
||||||
|
@ -230,6 +230,8 @@ def head_object(wif: str, cid: str, oid: str, bearer_token: str="",
|
||||||
turns into `--json` key
|
turns into `--json` key
|
||||||
is_raw(optional, bool): send "raw" request or not; this flag
|
is_raw(optional, bool): send "raw" request or not; this flag
|
||||||
turns into `--raw` key
|
turns into `--raw` key
|
||||||
|
is_direct(optional, bool): send request directly to the node or not; this flag
|
||||||
|
turns into `--ttl 1` key
|
||||||
Returns:
|
Returns:
|
||||||
depending on the `json_output` parameter value, the function returns
|
depending on the `json_output` parameter value, the function returns
|
||||||
(dict): HEAD response in JSON format
|
(dict): HEAD response in JSON format
|
||||||
|
@ -243,6 +245,7 @@ def head_object(wif: str, cid: str, oid: str, bearer_token: str="",
|
||||||
f'{"--bearer " + bearer_token if bearer_token else ""} '
|
f'{"--bearer " + bearer_token if bearer_token else ""} '
|
||||||
f'{"--json" if json_output else ""} '
|
f'{"--json" if json_output else ""} '
|
||||||
f'{"--raw" if is_raw else ""} '
|
f'{"--raw" if is_raw else ""} '
|
||||||
|
f'{"--ttl 1" if is_direct else ""}'
|
||||||
)
|
)
|
||||||
output = _cmd_run(cmd)
|
output = _cmd_run(cmd)
|
||||||
|
|
||||||
|
|
20
robot/resources/lib/robot/complex_object_operations.robot
Normal file
20
robot/resources/lib/robot/complex_object_operations.robot
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
*** Settings ***
|
||||||
|
Variables common.py
|
||||||
|
|
||||||
|
Library neofs_verbs.py
|
||||||
|
Library complex_object_operations.py
|
||||||
|
|
||||||
|
|
||||||
|
*** Keywords ***
|
||||||
|
|
||||||
|
Get Object Parts By Link Object
|
||||||
|
[Documentation] The keyword accepts the ID of a Large Object, retrieves its split
|
||||||
|
... header and returns all Part Object IDs from Link Object.
|
||||||
|
|
||||||
|
[Arguments] ${WIF} ${CID} ${LARGE_OID}
|
||||||
|
|
||||||
|
|
||||||
|
&{RESPONSE} = Get Link Object ${WIF} ${CID} ${LARGE_OID}
|
||||||
|
&{LINK_HEADER} = Head Object ${WIF} ${CID} ${RESPONSE.link} is_raw=True
|
||||||
|
|
||||||
|
[Return] ${LINK_HEADER.header.split.children}
|
|
@ -9,6 +9,7 @@ Library Collections
|
||||||
Resource common_steps_acl_basic.robot
|
Resource common_steps_acl_basic.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
|
@ -47,7 +48,8 @@ Check Private Container
|
||||||
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
${SG_OID} = Put Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID} = Put Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${SG_OID} ${SG_OID_INV}
|
List Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${SG_OID} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Delete Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID} ${EMPTY}
|
Delete Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID} ${EMPTY}
|
||||||
|
@ -67,7 +69,8 @@ Check Private Container
|
||||||
# System group key (Storage Node)
|
# System group key (Storage Node)
|
||||||
${SG_OID_SN} = Put Storagegroup ${NEOFS_SN_WIF} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_SN} = Put Storagegroup ${NEOFS_SN_WIF} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${NEOFS_SN_WIF} ${PRIV_CID} ${EMPTY} ${SG_OID_SN} ${SG_OID_INV}
|
List Storagegroup ${NEOFS_SN_WIF} ${PRIV_CID} ${EMPTY} ${SG_OID_SN} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${NEOFS_SN_WIF} ${PRIV_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${NEOFS_SN_WIF} ${PRIV_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${NEOFS_SN_WIF} ${PRIV_CID} ${SG_OID_SN} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${NEOFS_SN_WIF} ${PRIV_CID} ${SG_OID_SN} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
@ -77,7 +80,8 @@ Check Private Container
|
||||||
# System group key (Inner Ring Node)
|
# System group key (Inner Ring Node)
|
||||||
${SG_OID_IR} = Put Storagegroup ${NEOFS_IR_WIF} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_IR} = Put Storagegroup ${NEOFS_IR_WIF} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${NEOFS_IR_WIF} ${PRIV_CID} ${EMPTY} ${SG_OID_SN} ${SG_OID_IR} ${SG_OID_INV}
|
List Storagegroup ${NEOFS_IR_WIF} ${PRIV_CID} ${EMPTY} ${SG_OID_SN} ${SG_OID_IR} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${NEOFS_IR_WIF} ${PRIV_CID} ${SG_OID_IR} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${NEOFS_IR_WIF} ${PRIV_CID} ${SG_OID_IR} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
|
|
@ -9,6 +9,7 @@ Library contract_keywords.py
|
||||||
Resource common_steps_acl_basic.robot
|
Resource common_steps_acl_basic.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
|
@ -50,7 +51,8 @@ Check Public Container
|
||||||
FOR ${ROLE_KEY} IN @{ROLES_KEYS_PASS}
|
FOR ${ROLE_KEY} IN @{ROLES_KEYS_PASS}
|
||||||
${SG_OID_USERS} = Put Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${S_OID}
|
${SG_OID_USERS} = Put Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${S_OID}
|
||||||
List Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${SG_OID_USERS}
|
List Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${SG_OID_USERS}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${ROLE_KEY} ${PUBLIC_CID} ${S_OID}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${ROLE_KEY} ${PUBLIC_CID} ${S_OID}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID}
|
||||||
Get Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${SG_OID_USERS} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${SG_OID_USERS} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Delete Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${SG_OID_USERS} ${EMPTY}
|
Delete Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${SG_OID_USERS} ${EMPTY}
|
||||||
|
@ -59,7 +61,8 @@ Check Public Container
|
||||||
FOR ${ROLE_KEY} IN @{ROLES_KEYS_SYS}
|
FOR ${ROLE_KEY} IN @{ROLES_KEYS_SYS}
|
||||||
${SG_OID_SYS} = Put Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${S_OID}
|
${SG_OID_SYS} = Put Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${S_OID}
|
||||||
List Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${SG_OID_SYS}
|
List Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${EMPTY} ${SG_OID_SYS}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${ROLE_KEY} ${PUBLIC_CID} ${S_OID}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${ROLE_KEY} ${PUBLIC_CID} ${S_OID}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID}
|
||||||
Get Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${SG_OID_SYS} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${ROLE_KEY} ${PUBLIC_CID} ${SG_OID_SYS} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
|
|
@ -8,6 +8,7 @@ Library payment_neogo.py
|
||||||
Resource common_steps_acl_basic.robot
|
Resource common_steps_acl_basic.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
|
@ -50,7 +51,8 @@ Check Read-Only Container
|
||||||
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_1} ${SG_OID_INV}
|
List Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_1} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Delete Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY}
|
Delete Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY}
|
||||||
|
@ -58,7 +60,8 @@ Check Read-Only Container
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Put Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
... Put Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_INV}
|
List Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
@ -66,7 +69,8 @@ Check Read-Only Container
|
||||||
|
|
||||||
${SG_OID_IR} = Put Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_IR} = Put Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${SG_OID_INV} ${SG_OID_IR}
|
List Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${SG_OID_INV} ${SG_OID_IR}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${SG_OID_IR} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${SG_OID_IR} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
|
|
@ -8,6 +8,7 @@ Library payment_neogo.py
|
||||||
Resource common_steps_acl_basic.robot
|
Resource common_steps_acl_basic.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
|
@ -47,7 +48,8 @@ Check Read-Only Container
|
||||||
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_1} ${SG_OID_INV}
|
List Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_1} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Delete Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY}
|
Delete Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY}
|
||||||
|
@ -56,7 +58,8 @@ Check Read-Only Container
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Put Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
... Put Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_INV}
|
List Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
@ -65,7 +68,8 @@ Check Read-Only Container
|
||||||
|
|
||||||
${SG_OID_IR} = Put Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_IR} = Put Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${SG_OID_INV} ${SG_OID_IR}
|
List Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${EMPTY} ${SG_OID_INV} ${SG_OID_IR}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${SG_OID_IR} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${NEOFS_IR_WIF} ${READONLY_CID} ${SG_OID_IR} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
|
|
@ -11,6 +11,7 @@ Resource eacl_tables.robot
|
||||||
Resource common_steps_acl_bearer.robot
|
Resource common_steps_acl_bearer.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
|
@ -50,7 +51,8 @@ Check eACL Deny and Allow All Bearer
|
||||||
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
||||||
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
||||||
List Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${SG_OID_1} ${SG_OID_INV}
|
List Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${SG_OID_1} ${SG_OID_INV}
|
||||||
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${CID} ${S_OID_USER}
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex"
|
||||||
|
... Get Object Parts By Link Object ${USER_KEY} ${CID} ${S_OID_USER}
|
||||||
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
Get Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
Get Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${EMPTY} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
Delete Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${EMPTY}
|
Delete Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${EMPTY}
|
||||||
|
|
|
@ -13,6 +13,7 @@ Library Process
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
Resource storage.robot
|
Resource storage.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
*** Variables ***
|
*** Variables ***
|
||||||
${CONTAINER_WAIT_INTERVAL} = 1 min
|
${CONTAINER_WAIT_INTERVAL} = 1 min
|
||||||
|
@ -69,7 +70,7 @@ Drop command in control group
|
||||||
Get object ${USER_KEY} ${PRIV_CID} ${C_OID} ${EMPTY} s_file_read
|
Get object ${USER_KEY} ${PRIV_CID} ${C_OID} ${EMPTY} s_file_read
|
||||||
Head object ${USER_KEY} ${PRIV_CID} ${C_OID}
|
Head object ${USER_KEY} ${PRIV_CID} ${C_OID}
|
||||||
|
|
||||||
@{SPLIT_OIDS} = Get Split objects ${USER_KEY} ${PRIV_CID} ${C_OID}
|
@{SPLIT_OIDS} = Get Object Parts By Link Object ${USER_KEY} ${PRIV_CID} ${C_OID}
|
||||||
FOR ${CHILD_OID} IN @{SPLIT_OIDS}
|
FOR ${CHILD_OID} IN @{SPLIT_OIDS}
|
||||||
Drop object ${NODE} ${WIF} ${PRIV_CID} ${CHILD_OID}
|
Drop object ${NODE} ${WIF} ${PRIV_CID} ${CHILD_OID}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Variables common.py
|
Variables common.py
|
||||||
|
|
||||||
Library neofs_verbs.py
|
Library neofs_verbs.py
|
||||||
|
Library complex_object_actions.py
|
||||||
Library neofs.py
|
Library neofs.py
|
||||||
Library payment_neogo.py
|
Library payment_neogo.py
|
||||||
Library contract_keywords.py
|
Library contract_keywords.py
|
||||||
|
@ -15,6 +16,7 @@ Resource payment_operations.robot
|
||||||
${CLEANUP_TIMEOUT} = 10s
|
${CLEANUP_TIMEOUT} = 10s
|
||||||
&{FILE_USR_HEADER} = key1=1 key2=abc
|
&{FILE_USR_HEADER} = key1=1 key2=abc
|
||||||
&{FILE_USR_HEADER_OTH} = key1=2
|
&{FILE_USR_HEADER_OTH} = key1=2
|
||||||
|
${ALREADY_REMOVED_ERROR} = code = 1024 message = object already removed
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
|
@ -66,15 +68,23 @@ NeoFS Complex Object Operations
|
||||||
Search object ${WIF} ${CID} --root filters=${FILE_USR_HEADER} expected_objects_list=${S_OBJ_H}
|
Search object ${WIF} ${CID} --root filters=${FILE_USR_HEADER} expected_objects_list=${S_OBJ_H}
|
||||||
Search object ${WIF} ${CID} --root filters=${FILE_USR_HEADER_OTH} expected_objects_list=${S_OBJ_H_OTH}
|
Search object ${WIF} ${CID} --root filters=${FILE_USR_HEADER_OTH} expected_objects_list=${S_OBJ_H_OTH}
|
||||||
|
|
||||||
Head object ${WIF} ${CID} ${S_OID}
|
&{S_RESPONSE} = Head object ${WIF} ${CID} ${S_OID}
|
||||||
&{RESPONSE} = Head object ${WIF} ${CID} ${H_OID}
|
&{H_RESPONSE} = Head object ${WIF} ${CID} ${H_OID}
|
||||||
Dictionary Should Contain Sub Dictionary
|
Dictionary Should Contain Sub Dictionary
|
||||||
... ${RESPONSE}[header][attributes]
|
... ${H_RESPONSE}[header][attributes]
|
||||||
... ${FILE_USR_HEADER}
|
... ${FILE_USR_HEADER}
|
||||||
... msg="There are no User Headers in HEAD response"
|
... msg="There are no User Headers in HEAD response"
|
||||||
|
|
||||||
Verify Split Chain ${WIF} ${CID} ${S_OID}
|
${PAYLOAD_LENGTH} ${SPLIT_ID} ${SPLIT_OBJECTS} = Restore Large Object By Last
|
||||||
Verify Split Chain ${WIF} ${CID} ${H_OID}
|
... ${WIF} ${CID} ${S_OID}
|
||||||
|
${H_PAYLOAD_LENGTH} ${H_SPLIT_ID} ${H_SPLIT_OBJECTS} = Restore Large Object By Last
|
||||||
|
... ${WIF} ${CID} ${H_OID}
|
||||||
|
|
||||||
|
Compare With Link Object ${WIF} ${CID} ${S_OID} ${SPLIT_ID} ${SPLIT_OBJECTS}
|
||||||
|
Compare With Link Object ${WIF} ${CID} ${H_OID} ${H_SPLIT_ID} ${H_SPLIT_OBJECTS}
|
||||||
|
|
||||||
|
Should Be Equal As Numbers ${S_RESPONSE.header.payloadLength} ${PAYLOAD_LENGTH}
|
||||||
|
Should Be Equal As Numbers ${H_RESPONSE.header.payloadLength} ${H_PAYLOAD_LENGTH}
|
||||||
|
|
||||||
${TOMBSTONE_S} = Delete object ${WIF} ${CID} ${S_OID}
|
${TOMBSTONE_S} = Delete object ${WIF} ${CID} ${S_OID}
|
||||||
${TOMBSTONE_H} = Delete object ${WIF} ${CID} ${H_OID}
|
${TOMBSTONE_H} = Delete object ${WIF} ${CID} ${H_OID}
|
||||||
|
@ -86,9 +96,85 @@ NeoFS Complex Object Operations
|
||||||
# we assume that during this time objects must be deleted
|
# we assume that during this time objects must be deleted
|
||||||
Sleep ${CLEANUP_TIMEOUT}
|
Sleep ${CLEANUP_TIMEOUT}
|
||||||
|
|
||||||
Run Keyword And Expect Error "rpc error: status: code = 1024 message = object already removed"
|
${ERR_MSG} = Run Keyword And Expect Error *
|
||||||
... Get object ${WIF} ${CID} ${S_OID} ${EMPTY} ${GET_OBJ_S}
|
... Get object ${WIF} ${CID} ${S_OID}
|
||||||
Run Keyword And Expect Error "rpc error: status: code = 1024 message = object already removed"
|
Should Contain ${ERR_MSG} ${ALREADY_REMOVED_ERROR}
|
||||||
... Get object ${WIF} ${CID} ${H_OID} ${EMPTY} ${GET_OBJ_H}
|
${ERR_MSG} = Run Keyword And Expect Error *
|
||||||
|
... Get object ${WIF} ${CID} ${H_OID}
|
||||||
|
Should Contain ${ERR_MSG} ${ALREADY_REMOVED_ERROR}
|
||||||
|
|
||||||
[Teardown] Teardown object_complex
|
[Teardown] Teardown object_complex
|
||||||
|
|
||||||
|
|
||||||
|
*** Keywords ***
|
||||||
|
|
||||||
|
Restore Large Object By Last
|
||||||
|
[Documentation] In this keyword we assemble Large Object from its parts. First, we search for the
|
||||||
|
... Last Object; then, we try to restore the Large Object using Split Chain. We check
|
||||||
|
... that all Object Parts have identical SplitID, accumulate total payload length and
|
||||||
|
... compile a list of Object Parts. For the first part of split we also check if is
|
||||||
|
... has the only `splitID` field in the split header.
|
||||||
|
... The keyword returns total payload length, SplitID and list of Part Objects for
|
||||||
|
... these data might be verified by other keywords.
|
||||||
|
|
||||||
|
[Arguments] ${WIF} ${CID} ${LARGE_OID}
|
||||||
|
|
||||||
|
${LAST_OID} = Get Last Object ${WIF} ${CID} ${LARGE_OID}
|
||||||
|
&{LAST_OBJ_HEADER} = Head Object ${WIF} ${CID} ${LAST_OID} is_raw=True
|
||||||
|
Should Be Equal ${LARGE_OID} ${LAST_OBJ_HEADER.header.split.parent}
|
||||||
|
|
||||||
|
${SPLIT_ID} = Set Variable ${LAST_OBJ_HEADER.header.split.splitID}
|
||||||
|
${PART_OID} = Set Variable ${LAST_OBJ_HEADER.objectID}
|
||||||
|
${PAYLOAD_LENGTH} = Set Variable 0
|
||||||
|
@{PART_OBJECTS} = Create List
|
||||||
|
|
||||||
|
FOR ${i} IN RANGE 1000
|
||||||
|
&{SPLIT_HEADER} = Head object ${WIF} ${CID} ${PART_OID} is_raw=True
|
||||||
|
|
||||||
|
${PAYLOAD_LENGTH} = Evaluate ${PAYLOAD_LENGTH} + ${SPLIT_HEADER.header.payloadLength}
|
||||||
|
|
||||||
|
# Every Object of the given split contains the same SplitID
|
||||||
|
Should Be Equal ${SPLIT_HEADER.header.split.splitID} ${SPLIT_ID}
|
||||||
|
Should Be Equal ${SPLIT_HEADER.header.objectType} REGULAR
|
||||||
|
|
||||||
|
Append To List ${PART_OBJECTS} ${PART_OID}
|
||||||
|
|
||||||
|
# If we have reached the First Object, it has no `previous` field.
|
||||||
|
# Asserting this condition and exiting the loop.
|
||||||
|
${PASSED} = Run Keyword And Return Status
|
||||||
|
... Should Be Equal
|
||||||
|
... ${SPLIT_HEADER.header.split.previous} ${None}
|
||||||
|
|
||||||
|
Exit For Loop If ${PASSED}
|
||||||
|
${PART_OID} = Set Variable ${SPLIT_HEADER.header.split.previous}
|
||||||
|
END
|
||||||
|
|
||||||
|
[Return] ${PAYLOAD_LENGTH} ${SPLIT_ID} ${PART_OBJECTS}
|
||||||
|
|
||||||
|
|
||||||
|
Compare With Link Object
|
||||||
|
[Documentation] The keyword accepts Large Object SplitID and its Part Objects as
|
||||||
|
... a parameters. Then it requests the Link Object and verifies that
|
||||||
|
... a Split Chain which it stores is equal to the Part Objects list.
|
||||||
|
... In this way we check that Part Objects list restored from Last
|
||||||
|
... Object and the Split Chain from Link Object are equal and the
|
||||||
|
... system is able to restore the Large Object using any of these ways.
|
||||||
|
|
||||||
|
[Arguments] ${WIF} ${CID} ${LARGE_OID} ${SPLIT_ID} ${SPLIT_OBJECTS}
|
||||||
|
|
||||||
|
${LINK_OID} = Get Link Object ${WIF} ${CID} ${LARGE_OID}
|
||||||
|
&{LINK_HEADER} = Head Object ${WIF} ${CID} ${LINK_OID} is_raw=True
|
||||||
|
|
||||||
|
Reverse List ${SPLIT_OBJECTS}
|
||||||
|
Lists Should Be Equal
|
||||||
|
... ${LINK_HEADER.header.split.children}
|
||||||
|
... ${SPLIT_OBJECTS}
|
||||||
|
|
||||||
|
Should Be Equal As Numbers
|
||||||
|
... ${LINK_HEADER.header.payloadLength} 0
|
||||||
|
|
||||||
|
Should Be Equal
|
||||||
|
... ${LINK_HEADER.header.objectType} REGULAR
|
||||||
|
|
||||||
|
Should Be Equal
|
||||||
|
... ${LINK_HEADER.header.split.splitID} ${SPLIT_ID}
|
||||||
|
|
|
@ -9,6 +9,7 @@ Library Collections
|
||||||
Resource common_steps_object.robot
|
Resource common_steps_object.robot
|
||||||
Resource setup_teardown.robot
|
Resource setup_teardown.robot
|
||||||
Resource payment_operations.robot
|
Resource payment_operations.robot
|
||||||
|
Resource complex_object_operations.robot
|
||||||
|
|
||||||
*** Variables ***
|
*** Variables ***
|
||||||
${UNEXIST_OID} = B2DKvkHnLnPvapbDgfpU1oVUPuXQo5LTfKVxmNDZXQff
|
${UNEXIST_OID} = B2DKvkHnLnPvapbDgfpU1oVUPuXQo5LTfKVxmNDZXQff
|
||||||
|
@ -38,7 +39,7 @@ NeoFS Complex Storagegroup
|
||||||
Log Storage group with 1 object
|
Log Storage group with 1 object
|
||||||
${SG_OID_1} = Put Storagegroup ${WIF} ${CID} ${EMPTY} ${S_OID_1}
|
${SG_OID_1} = Put Storagegroup ${WIF} ${CID} ${EMPTY} ${S_OID_1}
|
||||||
List Storagegroup ${WIF} ${CID} ${EMPTY} ${SG_OID_1}
|
List Storagegroup ${WIF} ${CID} ${EMPTY} ${SG_OID_1}
|
||||||
@{SPLIT_OBJ_1} = Get Split objects ${WIF} ${CID} ${S_OID_1}
|
@{SPLIT_OBJ_1} = Get Object Parts By Link Object ${WIF} ${CID} ${S_OID_1}
|
||||||
Get Storagegroup ${WIF} ${CID} ${SG_OID_1} ${EMPTY} ${COMPLEX_OBJ_SIZE} @{SPLIT_OBJ_1}
|
Get Storagegroup ${WIF} ${CID} ${SG_OID_1} ${EMPTY} ${COMPLEX_OBJ_SIZE} @{SPLIT_OBJ_1}
|
||||||
${Tombstone} = Delete Storagegroup ${WIF} ${CID} ${SG_OID_1} ${EMPTY}
|
${Tombstone} = Delete Storagegroup ${WIF} ${CID} ${SG_OID_1} ${EMPTY}
|
||||||
Verify Head tombstone ${WIF} ${CID} ${Tombstone} ${SG_OID_1} ${ADDR}
|
Verify Head tombstone ${WIF} ${CID} ${Tombstone} ${SG_OID_1} ${ADDR}
|
||||||
|
@ -49,7 +50,7 @@ NeoFS Complex Storagegroup
|
||||||
Log Storage group with 2 objects
|
Log Storage group with 2 objects
|
||||||
${SG_OID_2} = Put Storagegroup ${WIF} ${CID} ${EMPTY} @{S_OBJ_ALL}
|
${SG_OID_2} = Put Storagegroup ${WIF} ${CID} ${EMPTY} @{S_OBJ_ALL}
|
||||||
List Storagegroup ${WIF} ${CID} ${EMPTY} ${SG_OID_2}
|
List Storagegroup ${WIF} ${CID} ${EMPTY} ${SG_OID_2}
|
||||||
@{SPLIT_OBJ_2} = Get Split objects ${WIF} ${CID} ${S_OID_2}
|
@{SPLIT_OBJ_2} = Get Object Parts By Link Object ${WIF} ${CID} ${S_OID_2}
|
||||||
@{SPLIT_OBJ_ALL} = Combine Lists ${SPLIT_OBJ_1} ${SPLIT_OBJ_2}
|
@{SPLIT_OBJ_ALL} = Combine Lists ${SPLIT_OBJ_1} ${SPLIT_OBJ_2}
|
||||||
${EXPECTED_SIZE} = Evaluate 2*${COMPLEX_OBJ_SIZE}
|
${EXPECTED_SIZE} = Evaluate 2*${COMPLEX_OBJ_SIZE}
|
||||||
Get Storagegroup ${WIF} ${CID} ${SG_OID_2} ${EMPTY} ${EXPECTED_SIZE} @{SPLIT_OBJ_ALL}
|
Get Storagegroup ${WIF} ${CID} ${SG_OID_2} ${EMPTY} ${EXPECTED_SIZE} @{SPLIT_OBJ_ALL}
|
||||||
|
|
Loading…
Reference in a new issue