forked from TrueCloudLab/frostfs-testcases
Additional linking object search (#38)
* Withdraw test case improvements * Additional linking object requests to detect issue details with unreturned Linking object
This commit is contained in:
parent
49cc629412
commit
0a47c0a815
17 changed files with 112 additions and 67 deletions
|
@ -412,19 +412,40 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s
|
|||
def get_component_objects(private_key: str, cid: str, oid: str):
|
||||
|
||||
logger.info("Collect Split objects list from Linked object.")
|
||||
split_id = ""
|
||||
nodes = _get_storage_nodes()
|
||||
for node in nodes:
|
||||
header_virtual = head_object(private_key, cid, oid, '', '', '--raw --ttl 1', node, True)
|
||||
parsed_header_virtual = parse_object_virtual_raw_header(header_virtual)
|
||||
if header_virtual:
|
||||
parsed_header_virtual = parse_object_virtual_raw_header(header_virtual)
|
||||
|
||||
if 'Linking object' in parsed_header_virtual.keys():
|
||||
if 'Linking object' in parsed_header_virtual.keys():
|
||||
return _collect_split_objects_from_header(private_key, cid, parsed_header_virtual)
|
||||
|
||||
header_link = head_object(private_key, cid, parsed_header_virtual['Linking object'], '', '', '--raw')
|
||||
header_link_parsed = parse_object_system_header(header_link)
|
||||
elif 'Split ID' in parsed_header_virtual.keys():
|
||||
logger.info(f"parsed_header_virtual: !@ {parsed_header_virtual}" )
|
||||
split_id = parsed_header_virtual['Split ID']
|
||||
|
||||
return header_link_parsed['Split ChildID']
|
||||
logger.warn("Linking object has not been found.")
|
||||
|
||||
# Get all existing objects
|
||||
full_obj_list = search_object(private_key, cid, None, None, None, None, '--phy')
|
||||
|
||||
# Search expected Linking object
|
||||
for targer_oid in full_obj_list:
|
||||
header = head_object(private_key, cid, targer_oid, '', '', '--raw')
|
||||
header_parsed = parse_object_system_header(header)
|
||||
if header_parsed['Split ID'] == split_id and 'Split ChildID' in header_parsed.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 = head_object(private_key, cid, parsed_header['Linking object'], '', '', '--raw')
|
||||
header_link_parsed = parse_object_system_header(header_link)
|
||||
return header_link_parsed['Split ChildID']
|
||||
|
||||
raise Exception("Linking object has not been found.")
|
||||
|
||||
|
||||
@keyword('Verify Split Chain')
|
||||
|
@ -689,76 +710,73 @@ def parse_object_system_header(header: str):
|
|||
|
||||
# ID
|
||||
m = re.search(r'^ID: (\w+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['ID'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no ID was parsed from object header: \t%s" % output)
|
||||
raise Exception("no ID was parsed from object header: \t%s" % header)
|
||||
|
||||
# CID
|
||||
m = re.search(r'CID: (\w+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['CID'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no CID was parsed from object header: \t%s" % output)
|
||||
raise Exception("no CID was parsed from object header: \t%s" % header)
|
||||
|
||||
# Owner
|
||||
m = re.search(r'Owner: ([a-zA-Z0-9]+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['OwnerID'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no OwnerID was parsed from object header: \t%s" % output)
|
||||
raise Exception("no OwnerID was parsed from object header: \t%s" % header)
|
||||
|
||||
# CreatedAtEpoch
|
||||
m = re.search(r'CreatedAt: (\d+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['CreatedAtEpoch'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no CreatedAtEpoch was parsed from object header: \t%s" % output)
|
||||
raise Exception("no CreatedAtEpoch was parsed from object header: \t%s" % header)
|
||||
|
||||
# PayloadLength
|
||||
m = re.search(r'Size: (\d+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['PayloadLength'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no PayloadLength was parsed from object header: \t%s" % output)
|
||||
raise Exception("no PayloadLength was parsed from object header: \t%s" % header)
|
||||
|
||||
# HomoHash
|
||||
m = re.search(r'HomoHash:\s+(\w+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['HomoHash'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no HomoHash was parsed from object header: \t%s" % output)
|
||||
raise Exception("no HomoHash was parsed from object header: \t%s" % header)
|
||||
|
||||
# Checksum
|
||||
m = re.search(r'Checksum:\s+(\w+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['Checksum'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no Checksum was parsed from object header: \t%s" % output)
|
||||
raise Exception("no Checksum was parsed from object header: \t%s" % header)
|
||||
|
||||
# Type
|
||||
m = re.search(r'Type:\s+(\w+)', header)
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
if m is not None:
|
||||
result_header['Type'] = m.group(1)
|
||||
else:
|
||||
raise Exception("no Type was parsed from object header: \t%s" % output)
|
||||
raise Exception("no Type was parsed from object header: \t%s" % header)
|
||||
|
||||
|
||||
# Header - Optional attributes
|
||||
m = re.search(r'Split ID:\s+([\w-]+)', header)
|
||||
if m != None:
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
result_header['Split ID'] = m.group(1)
|
||||
if m is not None:
|
||||
result_header['Split ID'] = m.group(1)
|
||||
|
||||
m = re.search(r'Split PreviousID:\s+(\w+)', header)
|
||||
if m != None:
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
result_header['Split PreviousID'] = m.group(1)
|
||||
if m is not None:
|
||||
result_header['Split PreviousID'] = m.group(1)
|
||||
|
||||
m = re.search(r'Split ParentID:\s+(\w+)', header)
|
||||
if m != None:
|
||||
if m.start() != m.end(): # e.g., if match found something
|
||||
result_header['Split ParentID'] = m.group(1)
|
||||
if m is not None:
|
||||
result_header['Split ParentID'] = m.group(1)
|
||||
|
||||
# Split ChildID list
|
||||
found_objects = re.findall(r'Split ChildID:\s+(\w+)', header)
|
||||
|
|
|
@ -121,14 +121,29 @@ def mainnet_balance(address: str):
|
|||
amount = m.group(1)
|
||||
return amount
|
||||
|
||||
@keyword('Expexted Mainnet Balance')
|
||||
@keyword('Expected Mainnet Balance')
|
||||
def expected_mainnet_balance(address: str, expected: float):
|
||||
amount = mainnet_balance(address)
|
||||
gas_expected = int(expected * 10**8)
|
||||
if int(amount) != int(gas_expected):
|
||||
raise Exception(f"Expected amount ({gas_expected}) of GAS has not been found. Found {amount}.")
|
||||
return amount
|
||||
|
||||
return True
|
||||
@keyword('Expected Mainnet Balance Diff')
|
||||
def expected_mainnet_balance_diff(address: str, old_value: float, expected_diff: float):
|
||||
amount = mainnet_balance(address)
|
||||
gas_expected = old_value + _convert_int_to_gas(expected_diff)
|
||||
if int(amount) != int(gas_expected):
|
||||
raise Exception(f"Balance amount ({int(amount)})) of GAS has not been changed for expected value:",
|
||||
f"{_convert_int_to_gas(expected_diff)} from initial {old_value}.",
|
||||
f"Expected: {old_value + _convert_int_to_gas(expected_diff)}")
|
||||
return amount
|
||||
|
||||
def _convert_int_to_gas(input_value: float):
|
||||
return int(input_value * 10**8)
|
||||
|
||||
def _convert_gas_to_int(input_value: float):
|
||||
return int(input_value / 10**8)
|
||||
|
||||
@keyword('NeoFS Deposit')
|
||||
def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int, wallet_pass:str=''):
|
||||
|
|
|
@ -39,13 +39,13 @@ Check eACL Deny and Allow All Bearer Filter Requst Equal
|
|||
@{S_OBJ_H} = Create List ${S_OID_USER}
|
||||
|
||||
Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_OTH_HEADER}
|
||||
Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
||||
Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||
Head object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
||||
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range ${EMPTY} 0:256
|
||||
Delete object ${USER_KEY} ${CID} ${D_OID_USER} ${EMPTY}
|
||||
Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
||||
Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||
Head object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
||||
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range ${EMPTY} 0:256
|
||||
Delete object ${USER_KEY} ${CID} ${D_OID_USER} ${EMPTY}
|
||||
|
||||
Set eACL ${USER_KEY} ${CID} ${EACL_DENY_ALL_USER} --await
|
||||
Set eACL ${USER_KEY} ${CID} ${EACL_DENY_ALL_USER} --await
|
||||
|
||||
${filters}= Create Dictionary headerType=REQUEST matchType=STRING_EQUAL key=a value=256
|
||||
${rule1}= Create Dictionary Operation=GET Access=ALLOW Role=USER Filters=${filters}
|
||||
|
|
|
@ -35,16 +35,16 @@ Check eACL Deny and Allow All Bearer Filter Requst NotEqual
|
|||
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
||||
${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${EMPTY}
|
||||
${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER_DEL}
|
||||
@{S_OBJ_H} = Create List ${S_OID_USER}
|
||||
@{S_OBJ_H} = Create List ${S_OID_USER}
|
||||
|
||||
Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_OTH_HEADER}
|
||||
Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
||||
Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||
Head object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
||||
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range ${EMPTY} 0:256
|
||||
Delete object ${USER_KEY} ${CID} ${D_OID_USER} ${EMPTY}
|
||||
Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
||||
Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||
Head object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
||||
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range ${EMPTY} 0:256
|
||||
Delete object ${USER_KEY} ${CID} ${D_OID_USER} ${EMPTY}
|
||||
|
||||
Set eACL ${USER_KEY} ${CID} ${EACL_DENY_ALL_USER} --await
|
||||
Set eACL ${USER_KEY} ${CID} ${EACL_DENY_ALL_USER} --await
|
||||
|
||||
${filters}= Create Dictionary headerType=REQUEST matchType=STRING_NOT_EQUAL key=a value=256
|
||||
${rule1}= Create Dictionary Operation=GET Access=ALLOW Role=USER Filters=${filters}
|
||||
|
|
|
@ -37,7 +37,7 @@ Payment Operations
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 3
|
||||
Expected Mainnet Balance ${ADDR} 3
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${KEY}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ Payment Operations
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 3
|
||||
Expected Mainnet Balance ${ADDR} 3
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${KEY}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ Payment Operations
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 3
|
||||
Expected Mainnet Balance ${ADDR} 3
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${KEY}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ Payment Operations
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 11
|
||||
Expected Mainnet Balance ${ADDR} 11
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${KEY}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ NeoFS Object Replication
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 11
|
||||
Expected Mainnet Balance ${ADDR} 11
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ NeoFS Complex Object Operations
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 15
|
||||
Expected Mainnet Balance ${ADDR} 15
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ NeoFS Simple Object Operations
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 15
|
||||
Expected Mainnet Balance ${ADDR} 15
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ NeoFS Complex Storagegroup
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 15
|
||||
Expected Mainnet Balance ${ADDR} 15
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ NeoFS Simple Storagegroup
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 15
|
||||
Expected Mainnet Balance ${ADDR} 15
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ Variables ../../../variables/common.py
|
|||
Library ../${RESOURCES}/neofs.py
|
||||
Library ../${RESOURCES}/payment_neogo.py
|
||||
|
||||
*** Variables ***
|
||||
${DEPOSIT_AMOUNT} = 10
|
||||
${WITHDRAW_AMOUNT} = 10
|
||||
|
||||
*** Test cases ***
|
||||
NeoFS Deposit and Withdraw
|
||||
[Documentation] Testcase to validate NeoFS Withdraw operation.
|
||||
|
@ -15,32 +19,39 @@ NeoFS Deposit and Withdraw
|
|||
${ADDR} = Dump Address ${WALLET}
|
||||
${PRIV_KEY} = Dump PrivKey ${WALLET} ${ADDR}
|
||||
|
||||
${TX} = Transfer Mainnet Gas wallets/wallet.json NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx ${ADDR} 55
|
||||
${TX} = Transfer Mainnet Gas wallets/wallet.json NTrezR3C4X8aMLVg7vozt5wguyNfFhwuFx ${ADDR} 15
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 55
|
||||
${MAINNET_BALANCE} = Expected Mainnet Balance ${ADDR} 15
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
||||
|
||||
${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} ${DEPOSIT_AMOUNT}
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX_DEPOSIT}
|
||||
Get Transaction ${TX_DEPOSIT}
|
||||
|
||||
Sleep 1 min
|
||||
|
||||
Expexted Mainnet Balance ${ADDR} 4.85067180
|
||||
# Expected amount diff will be formed from deposit amount and contract fee
|
||||
${EXPECTED_DIFF} = Evaluate -${DEPOSIT_AMOUNT}-${NEOFS_CONTRACT_DEPOSIT_GAS_FEE}
|
||||
${DEPOSIT_BALANCE} = Expected Mainnet Balance Diff ${ADDR} ${MAINNET_BALANCE} ${EXPECTED_DIFF}
|
||||
|
||||
${NEOFS_BALANCE} = Get Balance ${PRIV_KEY}
|
||||
|
||||
${TX} = Withdraw Mainnet Gas ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
||||
${TX} = Withdraw Mainnet Gas ${WALLET} ${ADDR} ${SCRIPT_HASH} ${WITHDRAW_AMOUNT}
|
||||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
|
||||
Sleep 1 min
|
||||
Get Balance ${PRIV_KEY}
|
||||
Expected Balance ${PRIV_KEY} ${NEOFS_BALANCE} -50
|
||||
Expexted Mainnet Balance ${ADDR} 54.81748270
|
||||
Expected Balance ${PRIV_KEY} ${NEOFS_BALANCE} -${WITHDRAW_AMOUNT}
|
||||
|
||||
# Expected amount diff will be formed from withdrawal amount and contract fee
|
||||
${EXPECTED_DIFF_W} = Evaluate ${WITHDRAW_AMOUNT}-${NEOFS_CONTRACT_WITHDRAW_GAS_FEE}
|
||||
Expected Mainnet Balance Diff ${ADDR} ${DEPOSIT_BALANCE} ${EXPECTED_DIFF_W}
|
||||
|
||||
[Teardown] Cleanup
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ NeoFS HTTP Gateway
|
|||
Wait Until Keyword Succeeds 1 min 15 sec
|
||||
... Transaction accepted in block ${TX}
|
||||
Get Transaction ${TX}
|
||||
Expexted Mainnet Balance ${ADDR} 6
|
||||
Expected Mainnet Balance ${ADDR} 6
|
||||
|
||||
${SCRIPT_HASH} = Get ScripHash ${PRIV_KEY}
|
||||
|
||||
|
|
|
@ -9,5 +9,6 @@ CERT="%s/../../ca" % ROOT
|
|||
# in case when test is run from root in docker
|
||||
ABSOLUTE_FILE_PATH="/robot/testsuites/integration"
|
||||
|
||||
MORPH_BLOCK_TIMEOUT = "10sec"
|
||||
NEOFS_EPOCH_TIMEOUT = "30sec"
|
||||
# Price of the contract Deposit execution: 0.1493182 GAS
|
||||
NEOFS_CONTRACT_DEPOSIT_GAS_FEE = 0.1493182
|
||||
NEOFS_CONTRACT_WITHDRAW_GAS_FEE = 0.0331791
|
Loading…
Reference in a new issue