[#205] storage policy validation reconsidered

Signed-off-by: anastasia prasolova <anastasia@nspcc.ru>
This commit is contained in:
anastasia prasolova 2022-05-26 12:44:13 +03:00 committed by Anastasia Prasolova
parent 8116ada7b6
commit e4c1c23ddd
9 changed files with 203 additions and 156 deletions

View file

@ -32,7 +32,7 @@ def get_scripthash(wif: str):
@keyword('Stop nodes') @keyword('Stop nodes')
def stop_nodes(down_num: int, *nodes_list): def stop_nodes(down_num: int, nodes_list: list):
# select nodes to stop from list # select nodes to stop from list
nodes = random.sample(nodes_list, down_num) nodes = random.sample(nodes_list, down_num)
@ -44,11 +44,11 @@ def stop_nodes(down_num: int, *nodes_list):
client = docker.APIClient() client = docker.APIClient()
client.stop(node) client.stop(node)
return stop_nodes return nodes
@keyword('Start nodes') @keyword('Start nodes')
def start_nodes(*nodes_list): def start_nodes(nodes_list: list):
for node in nodes_list: for node in nodes_list:
m = re.search(r'(s\d+).', node) m = re.search(r'(s\d+).', node)
@ -89,38 +89,6 @@ def get_nodes_without_object(wallet: str, cid: str, oid: str):
return nodes_list return nodes_list
@keyword('Validate storage policy for object')
def validate_storage_policy_for_object(wallet: str, expected_copies: int, cid, oid,
expected_node_list=[], storage_nodes=[]):
storage_nodes = storage_nodes if len(storage_nodes) != 0 else NEOFS_NETMAP
copies = 0
found_nodes = []
oid = oid.strip()
for node in storage_nodes:
res = _search_object(node, wallet, cid, oid)
if res:
if oid in res:
copies += 1
found_nodes.append(node)
if copies != expected_copies:
raise Exception("Object copies is not match storage policy."
f"Found: {copies}, expected: {expected_copies}.")
else:
logger.info(f"Found copies: {copies}, expected: {expected_copies}")
logger.info(f"Found nodes: {found_nodes}")
if expected_node_list:
if sorted(found_nodes) == sorted(expected_node_list):
logger.info(f"Found node list '{found_nodes}' "
f"is equal for expected list '{expected_node_list}'")
else:
raise Exception(f"Found node list '{found_nodes}' "
f"is not equal to expected list '{expected_node_list}'")
@keyword('Verify Head Tombstone') @keyword('Verify Head Tombstone')
def verify_head_tombstone(wallet: str, cid: str, oid_ts: str, oid: str, addr: str): def verify_head_tombstone(wallet: 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
@ -212,7 +180,7 @@ def get_logs_latest_timestamp():
log_line = client_api.logs(container, tail=1) log_line = client_api.logs(container, tail=1)
m = re.search(r'(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)', str(log_line)) m = re.search(r'(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)', str(log_line))
if m != None: if m is not None:
timestamp = m.group(1) timestamp = m.group(1)
timestamp_date = datetime.fromisoformat(timestamp[:-1]) timestamp_date = datetime.fromisoformat(timestamp[:-1])
@ -307,29 +275,6 @@ def sign_session_token(session_token: str, wallet: str, to_file: str=''):
_cmd_run(cmd) _cmd_run(cmd)
def _parse_oid(input_str: str):
"""
This function parses OID from given CLI output. The input string we
expect:
Object successfully stored
ID: 4MhrLA7RXTBXCsaNnbahYVAPuoQdiUPuyNEWnywvoSEs
CID: HeZu2DXBuPve6HXbuHZx64knS7KcGtfSj2L59Li72kkg
We want to take 'ID' value from the string.
Parameters:
- input_str: a string with command run output
"""
try:
# taking second string from command output
snd_str = input_str.split('\n')[1]
except:
logger.error(f"Got empty input: {input_str}")
splitted = snd_str.split(": ")
if len(splitted) != 2:
raise Exception(f"no OID was parsed from command output: \t{snd_str}")
return splitted[1]
def _search_object(node:str, wallet: str, cid:str, oid: str): def _search_object(node:str, wallet: str, cid:str, oid: str):
cmd = ( cmd = (
f'{NEOFS_CLI_EXEC} --rpc-endpoint {node} --wallet {wallet} --ttl 1 ' f'{NEOFS_CLI_EXEC} --rpc-endpoint {node} --wallet {wallet} --ttl 1 '

View file

@ -247,7 +247,12 @@ def head_object(wallet: str, cid: str, oid: str, bearer_token: str="",
f'{"--raw" if is_raw else ""} ' f'{"--raw" if is_raw else ""} '
f'{"--ttl 1" if is_direct else ""}' f'{"--ttl 1" if is_direct else ""}'
) )
output = _cmd_run(cmd) output = None
try:
output = _cmd_run(cmd)
except Exception as exc:
logger.info(f"Head request failed with output: {output}")
return None
if not json_output: if not json_output:
return output return output

View file

@ -0,0 +1,79 @@
#!/usr/bin/python3
'''
This module contains keywords which are used for asserting
that storage policies are kept.
'''
from common import NEOFS_NETMAP
import complex_object_actions
import neofs_verbs
from robot.api.deco import keyword
ROBOT_AUTO_KEYWORDS = False
@keyword('Get Object Copies')
def get_object_copies(complexity: str, wallet: str, cid: str, oid: str):
"""
The function performs requests to all nodes of the container and
finds out if they store a copy of the object. The procedure is
different for simple and complex object, so the function requires
a sign of object complexity.
Args:
complexity (str): the tag of object size and complexity,
[Simple|Complex]
wallet (str): the path to the wallet on whose behalf the
copies are got
cid (str): ID of the container
oid (str): ID of the Object
Returns:
(int): the number of object copies in the container
"""
return (get_simple_object_copies(wallet, cid, oid) if complexity == "Simple"
else get_complex_object_copies(wallet, cid, oid))
@keyword('Get Simple Object Copies')
def get_simple_object_copies(wallet: str, cid: str, oid: str):
"""
To figure out the number of a simple object copies, only direct
HEAD requests should be made to the every node of the container.
We consider non-empty HEAD response as a stored object copy.
Args:
wallet (str): the path to the wallet on whose behalf the
copies are got
cid (str): ID of the container
oid (str): ID of the Object
Returns:
(int): the number of object copies in the container
"""
copies = 0
for node in NEOFS_NETMAP:
response = neofs_verbs.head_object(wallet, cid, oid,
endpoint=node,
is_direct=True)
if response:
copies += 1
return copies
@keyword('Get Complex Object Copies')
def get_complex_object_copies(wallet: str, cid: str, oid: str):
"""
To figure out the number of a complex object copies, we firstly
need to retrieve its Last object. We consider that the number of
complex object copies is equal to the number of its last object
copies. When we have the Last object ID, the task is reduced
to getting simple object copies.
Args:
wallet (str): the path to the wallet on whose behalf the
copies are got
cid (str): ID of the container
oid (str): ID of the Object
Returns:
(int): the number of object copies in the container
"""
last_oid = complex_object_actions.get_last_object(wallet, cid, oid)
return get_simple_object_copies(wallet, cid, last_oid)

View file

@ -49,7 +49,6 @@ def get_file_hash(filename: str):
with open(filename, "rb") as out: with open(filename, "rb") as out:
for block in iter(lambda: out.read(blocksize), b""): for block in iter(lambda: out.read(blocksize), b""):
file_hash.update(block) file_hash.update(block)
logger.info(f"Hash: {file_hash.hexdigest()}")
return file_hash.hexdigest() return file_hash.hexdigest()

View file

@ -1,11 +1,12 @@
*** Settings *** *** Settings ***
Variables common.py Variables common.py
Library acl.py
Library container.py Library container.py
Library contract_keywords.py
Library neofs.py Library neofs.py
Library neofs_verbs.py Library neofs_verbs.py
Library acl.py Library storage_policy.py
Library contract_keywords.py
Library utility_keywords.py Library utility_keywords.py
Resource eacl_tables.robot Resource eacl_tables.robot
@ -17,8 +18,6 @@ Resource storage.robot
*** Variables *** *** Variables ***
${FULL_PLACEMENT_RULE} = REP 4 IN X CBF 1 SELECT 4 FROM * AS X ${FULL_PLACEMENT_RULE} = REP 4 IN X CBF 1 SELECT 4 FROM * AS X
${EXPECTED_COPIES} = ${4} ${EXPECTED_COPIES} = ${4}
${DEPOSIT} = ${30}
*** Test cases *** *** Test cases ***
eACL Deny Replication Operations eACL Deny Replication Operations
@ -41,7 +40,8 @@ eACL Deny Replication Operations
${OID} = Put object ${WALLET} ${FILE} ${CID} ${OID} = Put object ${WALLET} ${FILE} ${CID}
Validate storage policy for object ${WALLET} ${EXPECTED_COPIES} ${CID} ${OID} ${COPIES} = Get Object Copies Simple ${WALLET} ${CID} ${OID}
Should Be Equal As Numbers ${EXPECTED_COPIES} ${COPIES}
Set eACL ${WALLET} ${CID} ${EACL_DENY_ALL_USER} Set eACL ${WALLET} ${CID} ${EACL_DENY_ALL_USER}
@ -52,9 +52,11 @@ eACL Deny Replication Operations
Drop object ${NODE} ${WALLET_STORAGE} ${CID} ${OID} Drop object ${NODE} ${WALLET_STORAGE} ${CID} ${OID}
Tick Epoch Tick Epoch
Sleep ${NEOFS_CONTRACT_CACHE_TIMEOUT}
# We assume that during one epoch object should be replicated # We assume that during one epoch object should be replicated
Wait Until Keyword Succeeds ${NEOFS_EPOCH_TIMEOUT} 1m ${COPIES} = Get Object Copies Simple ${WALLET_STORAGE} ${CID} ${OID}
... Validate storage policy for object ${WALLET_STORAGE} ${EXPECTED_COPIES} ${CID} ${OID} Should Be Equal As Numbers ${EXPECTED_COPIES} ${COPIES}
... msg="Dropped object should be replicated in one epoch"
[Teardown] Teardown acl_deny_replication [Teardown] Teardown acl_deny_replication

View file

@ -4,14 +4,14 @@ Variables common.py
Library container.py Library container.py
Library neofs.py Library neofs.py
Library neofs_verbs.py Library neofs_verbs.py
Library storage_policy.py
Library utility_keywords.py Library utility_keywords.py
Library Collections
Resource payment_operations.robot Resource payment_operations.robot
Resource setup_teardown.robot Resource setup_teardown.robot
*** Variables ***
${CONTAINER_WAIT_INTERVAL} = 1 min
*** Test cases *** *** Test cases ***
NeoFS Simple Netmap NeoFS Simple Netmap
[Documentation] Testcase to validate NeoFS Netmap. [Documentation] Testcase to validate NeoFS Netmap.
@ -21,66 +21,77 @@ NeoFS Simple Netmap
[Setup] Setup [Setup] Setup
${WALLET} ${_} ${_} = Prepare Wallet And Deposit ${WALLET} ${_} ${_} = Prepare Wallet And Deposit
${FILE} ${_} = Generate file ${SIMPLE_OBJ_SIZE}
Validate Policy ${WALLET} ${FILE} REP 2 IN X CBF 2 SELECT 2 FROM * AS X 2 @{EMPTY} Validate Object Copies ${WALLET} REP 2 IN X CBF 2 SELECT 2 FROM * AS X 2
Validate Policy ${WALLET} ${FILE} REP 2 IN X CBF 1 SELECT 2 FROM * AS X 2 @{EMPTY} Validate Object Copies ${WALLET} REP 2 IN X CBF 1 SELECT 2 FROM * AS X 2
Validate Policy ${WALLET} ${FILE} REP 3 IN X CBF 1 SELECT 3 FROM * AS X 3 @{EMPTY} Validate Object Copies ${WALLET} REP 3 IN X CBF 1 SELECT 3 FROM * AS X 3
Validate Policy ${WALLET} ${FILE} REP 1 IN X CBF 1 SELECT 1 FROM * AS X 1 @{EMPTY} Validate Object Copies ${WALLET} REP 1 IN X CBF 1 SELECT 1 FROM * AS X 1
Validate Policy ${WALLET} ${FILE} REP 1 IN X CBF 2 SELECT 1 FROM * AS X 1 @{EMPTY} Validate Object Copies ${WALLET} REP 1 IN X CBF 2 SELECT 1 FROM * AS X 1
Validate Policy ${WALLET} ${FILE} REP 4 IN X CBF 1 SELECT 4 FROM * AS X 4 @{EMPTY} Validate Object Copies ${WALLET} REP 4 IN X CBF 1 SELECT 4 FROM * AS X 4
Validate Policy ${WALLET} ${FILE} REP 2 IN X CBF 1 SELECT 4 FROM * AS X 2 @{EMPTY} Validate Object Copies ${WALLET} REP 2 IN X CBF 1 SELECT 4 FROM * AS X 2
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 s03.neofs.devenv:8080 s04.neofs.devenv:8080 @{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 s03.neofs.devenv:8080 s04.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 4 IN X CBF 1 SELECT 4 FROM * AS X 4 @{EXPECTED} Validate Selected Nodes ${WALLET} REP 4 IN X CBF 1 SELECT 4 FROM * AS X 4 @{EXPECTED}
@{EXPECTED} = Create List s03.neofs.devenv:8080 @{EXPECTED} = Create List s03.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 1 IN LOC_PLACE CBF 1 SELECT 1 FROM LOC_SW AS LOC_PLACE FILTER Country EQ Sweden AS LOC_SW Validate Selected Nodes ${WALLET} REP 1 IN LOC_PLACE CBF 1 SELECT 1 FROM LOC_SW AS LOC_PLACE FILTER Country EQ Sweden AS LOC_SW
... 1 @{EXPECTED} ... 1 @{EXPECTED}
@{EXPECTED} = Create List s02.neofs.devenv:8080 @{EXPECTED} = Create List s02.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER 'UN-LOCODE' EQ 'RU LED' AS LOC_SPB 1 @{EXPECTED} Validate Selected Nodes ${WALLET} REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER 'UN-LOCODE' EQ 'RU LED' AS LOC_SPB 1 @{EXPECTED}
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 @{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 1 IN LOC_SPB_PLACE REP 1 IN LOC_MSK_PLACE CBF 1 SELECT 1 FROM LOC_SPB AS LOC_SPB_PLACE SELECT 1 FROM LOC_MSK AS LOC_MSK_PLACE FILTER 'UN-LOCODE' EQ 'RU LED' AS LOC_SPB FILTER 'UN-LOCODE' EQ 'RU MOW' AS LOC_MSK Validate Selected Nodes ${WALLET}
... 2 @{EXPECTED} ... REP 1 IN LOC_SPB_PLACE REP 1 IN LOC_MSK_PLACE CBF 1 SELECT 1 FROM LOC_SPB AS LOC_SPB_PLACE SELECT 1 FROM LOC_MSK AS LOC_MSK_PLACE FILTER 'UN-LOCODE' EQ 'RU LED' AS LOC_SPB FILTER 'UN-LOCODE' EQ 'RU MOW' AS LOC_MSK
... 2 @{EXPECTED}
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 s03.neofs.devenv:8080 s04.neofs.devenv:8080 @{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 s03.neofs.devenv:8080 s04.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 4 CBF 1 SELECT 4 FROM LOC_EU FILTER Continent EQ Europe AS LOC_EU 4 @{EXPECTED} Validate Selected Nodes ${WALLET} REP 4 CBF 1 SELECT 4 FROM LOC_EU FILTER Continent EQ Europe AS LOC_EU 4 @{EXPECTED}
@{EXPECTED} = Create List s02.neofs.devenv:8080 @{EXPECTED} = Create List s02.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER 'UN-LOCODE' NE 'RU MOW' AND 'UN-LOCODE' NE 'SE STO' AND 'UN-LOCODE' NE 'FI HEL' AS LOC_SPB Validate Selected Nodes ${WALLET}
... 1 @{EXPECTED} ... REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER 'UN-LOCODE' NE 'RU MOW' AND 'UN-LOCODE' NE 'SE STO' AND 'UN-LOCODE' NE 'FI HEL' AS LOC_SPB
... 1 @{EXPECTED}
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 @{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER SubDivCode NE 'AB' AND SubDivCode NE '18' AS LOC_RU 2 @{EXPECTED} Validate Selected Nodes ${WALLET} REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER SubDivCode NE 'AB' AND SubDivCode NE '18' AS LOC_RU 2 @{EXPECTED}
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 @{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER Country EQ 'Russia' AS LOC_RU 2 @{EXPECTED} Validate Selected Nodes ${WALLET} REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER Country EQ 'Russia' AS LOC_RU 2 @{EXPECTED}
@{EXPECTED} = Create List s03.neofs.devenv:8080 s04.neofs.devenv:8080 @{EXPECTED} = Create List s03.neofs.devenv:8080 s04.neofs.devenv:8080
Validate Policy ${WALLET} ${FILE} REP 2 CBF 1 SELECT 2 FROM LOC_EU FILTER Country NE 'Russia' AS LOC_EU 2 @{EXPECTED} Validate Selected Nodes ${WALLET} REP 2 CBF 1 SELECT 2 FROM LOC_EU FILTER Country NE 'Russia' AS LOC_EU 2 @{EXPECTED}
Log Put operation should be failed with error "not enough nodes to SELECT from: 'X'" ${ERR} = Run Keyword And Expect Error *
Run Keyword And Expect Error * ... Validate Selected Nodes ${WALLET} REP 2 IN X CBF 2 SELECT 6 FROM * AS X 2
... Validate Policy ${WALLET} ${FILE} REP 2 IN X CBF 2 SELECT 6 FROM * AS X 2 @{EMPTY} Should Contain ${ERR} code = 1024 message = netmap: not enough nodes to SELECT from
[Teardown] Teardown netmap_simple [Teardown] Teardown netmap_simple
*** Keywords *** *** Keywords ***
Validate Policy Validate Object Copies
[Arguments] ${WALLET} ${FILE} ${POLICY} ${EXPECTED_VAL} @{EXPECTED_LIST} [Arguments] ${WALLET} ${POLICY} ${EXPECTED_COPIES}
Log Container with rule ${POLICY} ${FILE}
... ${_} = Generate file ${SIMPLE_OBJ_SIZE}
${CID} = Create container ${WALLET} rule=${POLICY}
${OID} = Put object ${WALLET} ${FILE} ${CID}
${COPIES} = Get Simple Object Copies ${WALLET} ${CID} ${OID}
Should Be Equal As Numbers ${EXPECTED_COPIES} ${COPIES}
[Return] ${CID} ${OID}
${CID} = Create container ${WALLET} rule=${POLICY}
${S_OID} = Put object ${WALLET} ${FILE} ${CID} Validate Selected Nodes
Validate storage policy for object ${WALLET} ${EXPECTED_VAL} ${CID} ${S_OID} ${EXPECTED_LIST} [Arguments] ${WALLET} ${POLICY} ${EXPECTED_COPIES} @{EXPECTED_NODES}
Get object ${WALLET} ${CID} ${S_OID} ${EMPTY} s_file_read
${CID}
... ${OID} = Validate Object Copies ${WALLET} ${POLICY} ${EXPECTED_COPIES}
${NODES} = Get Nodes With Object ${WALLET} ${CID} ${OID}
Lists Should Be Equal ${EXPECTED_NODES} ${NODES}

View file

@ -3,9 +3,10 @@ Variables common.py
Variables wellknown_acl.py Variables wellknown_acl.py
Library container.py Library container.py
Library contract_keywords.py
Library neofs.py Library neofs.py
Library neofs_verbs.py Library neofs_verbs.py
Library contract_keywords.py Library storage_policy.py
Library utility_keywords.py Library utility_keywords.py
Library Collections Library Collections
@ -15,7 +16,6 @@ Resource setup_teardown.robot
*** Variables *** *** Variables ***
${EXPECTED_COPIES} = ${2} ${EXPECTED_COPIES} = ${2}
${CHECK_INTERVAL} = 1 min
*** Test cases *** *** Test cases ***
NeoFS Object Replication NeoFS Object Replication
@ -26,7 +26,7 @@ NeoFS Object Replication
[Setup] Setup [Setup] Setup
Log Check replication mechanism Log Check replication mechanism
Check Replication ${EMPTY} Check Replication
Log Check Sticky Bit with SYSTEM Group via replication mechanism Log Check Sticky Bit with SYSTEM Group via replication mechanism
Check Replication ${STICKYBIT_PUB_ACL} Check Replication ${STICKYBIT_PUB_ACL}
@ -34,7 +34,7 @@ NeoFS Object Replication
*** Keywords *** *** Keywords ***
Check Replication Check Replication
[Arguments] ${ACL} [Arguments] ${ACL}=${EMPTY}
${WALLET} ${_} ${_} = Prepare Wallet And Deposit ${WALLET} ${_} ${_} = Prepare Wallet And Deposit
${CID} = Create Container ${WALLET} basic_acl=${ACL} ${CID} = Create Container ${WALLET} basic_acl=${ACL}
@ -42,36 +42,41 @@ Check Replication
${FILE} ${_} = Generate file ${SIMPLE_OBJ_SIZE} ${FILE} ${_} = Generate file ${SIMPLE_OBJ_SIZE}
${S_OID} = Put Object ${WALLET} ${FILE} ${CID} ${S_OID} = Put Object ${WALLET} ${FILE} ${CID}
Validate storage policy for object ${WALLET} ${EXPECTED_COPIES} ${CID} ${S_OID}
${COPIES} = Get Object Copies Simple ${WALLET} ${CID} ${S_OID}
Should Be Equal ${EXPECTED_COPIES} ${COPIES}
@{NODES_OBJ} = Get nodes with Object ${WALLET} ${CID} ${S_OID} @{NODES_OBJ} = Get nodes with Object ${WALLET} ${CID} ${S_OID}
${NODES_LOG_TIME} = Get Nodes Log Latest Timestamp ${NODES_LOG_TIME} = Get Nodes Log Latest Timestamp
@{NODES_OBJ_STOPPED} = Stop nodes 1 @{NODES_OBJ} @{NODES_OBJ_STOPPED} = Stop nodes 1 ${NODES_OBJ}
@{NETMAP} = Convert To List ${NEOFS_NETMAP} @{NETMAP} = Convert To List ${NEOFS_NETMAP}
Remove Values From List ${NETMAP} @{NODES_OBJ_STOPPED} Remove Values From List ${NETMAP} ${NODES_OBJ_STOPPED}
# We expect that during two epochs the missed copy will be replicated. # We expect that during two epochs the missed copy will be replicated.
FOR ${i} IN RANGE 2 FOR ${i} IN RANGE 2
${COPIES} = Get Object Copies Simple ${WALLET} ${CID} ${S_OID}
${PASSED} = Run Keyword And Return Status ${PASSED} = Run Keyword And Return Status
... Validate storage policy for object ${WALLET} ${EXPECTED_COPIES} ... Should Be Equal ${EXPECTED_COPIES} ${COPIES}
... ${CID} ${S_OID} ${EMPTY} ${NETMAP}
Exit For Loop If ${PASSED} Exit For Loop If ${PASSED}
Tick Epoch Tick Epoch
Sleep ${CHECK_INTERVAL} Sleep ${NEOFS_CONTRACT_CACHE_TIMEOUT}
END END
Run Keyword Unless ${PASSED} Fail Keyword failed: Validate storage policy for object ${S_OID} in container ${CID} Run Keyword Unless ${PASSED} Fail
... Storage policy for object ${S_OID} in container ${CID} isn't valid
Find in Nodes Log object successfully replicated ${NODES_LOG_TIME} Find in Nodes Log object successfully replicated ${NODES_LOG_TIME}
Start nodes @{NODES_OBJ_STOPPED} Start nodes ${NODES_OBJ_STOPPED}
Tick Epoch Tick Epoch
# We have 2 or 3 copies. Expected behaviour: during two epochs potential 3rd copy should be removed. # We have 2 or 3 copies. Expected behaviour: during two epochs potential 3rd copy should be removed.
FOR ${i} IN RANGE 2 FOR ${i} IN RANGE 2
${COPIES} = Get Object Copies Simple ${WALLET} ${CID} ${S_OID}
${PASSED} = Run Keyword And Return Status ${PASSED} = Run Keyword And Return Status
... Validate storage policy for object ${WALLET} ${EXPECTED_COPIES} ${CID} ${S_OID} ... Should Be Equal ${EXPECTED_COPIES} ${COPIES}
Exit For Loop If ${PASSED} Exit For Loop If ${PASSED}
Tick Epoch Tick Epoch
Sleep ${CHECK_INTERVAL} Sleep ${NEOFS_CONTRACT_CACHE_TIMEOUT}
END END
Run Keyword Unless ${PASSED} Fail Keyword failed: Validate storage policy for object ${S_OID} in container ${CID} Run Keyword Unless ${PASSED} Fail
... Storage policy for object ${S_OID} in container ${CID} isn't valid

View file

@ -1,22 +1,24 @@
*** Settings *** *** Settings ***
Variables common.py Variables common.py
Library neofs_verbs.py
Library container.py Library container.py
Library complex_object_actions.py Library complex_object_actions.py
Library neofs.py
Library contract_keywords.py Library contract_keywords.py
Library Collections Library neofs_verbs.py
Library neofs.py
Library storage_policy.py
Library utility_keywords.py Library utility_keywords.py
Library Collections
Resource setup_teardown.robot Resource setup_teardown.robot
Resource payment_operations.robot Resource payment_operations.robot
*** Variables *** *** Variables ***
${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 ${ALREADY_REMOVED_ERROR} = code = 2052 message = object already removed
${ALREADY_REMOVED_ERROR} = code = 1024 message = object already removed
*** Test cases *** *** Test cases ***
@ -34,19 +36,13 @@ NeoFS Complex Object Operations
${S_OID} = Put object ${WALLET} ${FILE} ${CID} ${S_OID} = Put object ${WALLET} ${FILE} ${CID}
${H_OID} = Put object ${WALLET} ${FILE} ${CID} user_headers=${FILE_USR_HEADER} ${H_OID} = Put object ${WALLET} ${FILE} ${CID} user_headers=${FILE_USR_HEADER}
${H_OID_OTH} = Put object ${WALLET} ${FILE} ${CID} user_headers=${FILE_USR_HEADER_OTH}
Should Be True '${S_OID}'!='${H_OID}' and '${H_OID}'!='${H_OID_OTH}' Should Not Be Equal ${H_OID} ${S_OID}
Validate storage policy for object ${WALLET} 2 ${CID} ${S_OID} ${COPIES} = Get Complex Object Copies ${WALLET} ${CID} ${S_OID}
Validate storage policy for object ${WALLET} 2 ${CID} ${H_OID} Should Be Equal As Numbers 2 ${COPIES}
Validate storage policy for object ${WALLET} 2 ${CID} ${H_OID_OTH} ${COPIES} = Get Complex Object Copies ${WALLET} ${CID} ${H_OID}
Should Be Equal As Numbers 2 ${COPIES}
@{S_OBJ_ALL} = Create List ${S_OID} ${H_OID} ${H_OID_OTH}
@{S_OBJ_H} = Create List ${H_OID}
@{S_OBJ_H_OTH} = Create List ${H_OID_OTH}
Search Object ${WALLET} ${CID} --root expected_objects_list=${S_OBJ_ALL}
${GET_OBJ_S} = Get object ${WALLET} ${CID} ${S_OID} ${GET_OBJ_S} = Get object ${WALLET} ${CID} ${S_OID}
${GET_OBJ_H} = Get object ${WALLET} ${CID} ${H_OID} ${GET_OBJ_H} = Get object ${WALLET} ${CID} ${H_OID}
@ -63,9 +59,11 @@ NeoFS Complex Object Operations
Get Range ${WALLET} ${CID} ${S_OID} s_get_range ${EMPTY} 0:10 Get Range ${WALLET} ${CID} ${S_OID} s_get_range ${EMPTY} 0:10
Get Range ${WALLET} ${CID} ${H_OID} h_get_range ${EMPTY} 0:10 Get Range ${WALLET} ${CID} ${H_OID} h_get_range ${EMPTY} 0:10
@{S_OBJ_ALL} = Create List ${S_OID} ${H_OID}
@{S_OBJ_H} = Create List ${H_OID}
Search object ${WALLET} ${CID} --root expected_objects_list=${S_OBJ_ALL} Search object ${WALLET} ${CID} --root expected_objects_list=${S_OBJ_ALL}
Search object ${WALLET} ${CID} --root filters=${FILE_USR_HEADER} expected_objects_list=${S_OBJ_H} Search object ${WALLET} ${CID} --root filters=${FILE_USR_HEADER} expected_objects_list=${S_OBJ_H}
Search object ${WALLET} ${CID} --root filters=${FILE_USR_HEADER_OTH} expected_objects_list=${S_OBJ_H_OTH}
&{S_RESPONSE} = Head object ${WALLET} ${CID} ${S_OID} &{S_RESPONSE} = Head object ${WALLET} ${CID} ${S_OID}
&{H_RESPONSE} = Head object ${WALLET} ${CID} ${H_OID} &{H_RESPONSE} = Head object ${WALLET} ${CID} ${H_OID}
@ -74,9 +72,13 @@ NeoFS Complex Object Operations
... ${FILE_USR_HEADER} ... ${FILE_USR_HEADER}
... msg="There are no User Headers in HEAD response" ... msg="There are no User Headers in HEAD response"
${PAYLOAD_LENGTH} ${SPLIT_ID} ${SPLIT_OBJECTS} = Restore Large Object By Last ${PAYLOAD_LENGTH}
... ${SPLIT_ID}
... ${SPLIT_OBJECTS} = Restore Large Object By Last
... ${WALLET} ${CID} ${S_OID} ... ${WALLET} ${CID} ${S_OID}
${H_PAYLOAD_LENGTH} ${H_SPLIT_ID} ${H_SPLIT_OBJECTS} = Restore Large Object By Last ${H_PAYLOAD_LENGTH}
... ${H_SPLIT_ID}
... ${H_SPLIT_OBJECTS} = Restore Large Object By Last
... ${WALLET} ${CID} ${H_OID} ... ${WALLET} ${CID} ${H_OID}
Compare With Link Object ${WALLET} ${CID} ${S_OID} ${SPLIT_ID} ${SPLIT_OBJECTS} Compare With Link Object ${WALLET} ${CID} ${S_OID} ${SPLIT_ID} ${SPLIT_OBJECTS}

View file

@ -1,20 +1,21 @@
*** Settings *** *** Settings ***
Variables common.py Variables common.py
Library neofs.py
Library neofs_verbs.py
Library container.py Library container.py
Library contract_keywords.py Library contract_keywords.py
Library Collections Library neofs.py
Library neofs_verbs.py
Library storage_policy.py
Library utility_keywords.py Library utility_keywords.py
Library Collections
Resource payment_operations.robot Resource payment_operations.robot
Resource setup_teardown.robot Resource setup_teardown.robot
*** Variables *** *** Variables ***
${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
*** Test cases *** *** Test cases ***
@ -32,15 +33,14 @@ NeoFS Simple Object Operations
${S_OID} = Put object ${WALLET} ${FILE} ${CID} ${S_OID} = Put object ${WALLET} ${FILE} ${CID}
${H_OID} = Put object ${WALLET} ${FILE} ${CID} user_headers=${FILE_USR_HEADER} ${H_OID} = Put object ${WALLET} ${FILE} ${CID} user_headers=${FILE_USR_HEADER}
${H_OID_OTH} = Put object ${WALLET} ${FILE} ${CID} user_headers=${FILE_USR_HEADER_OTH}
Validate storage policy for object ${WALLET} 2 ${CID} ${S_OID} ${COPIES} = Get Simple Object Copies ${WALLET} ${CID} ${S_OID}
Validate storage policy for object ${WALLET} 2 ${CID} ${H_OID} Should Be Equal As Numbers 2 ${COPIES}
Validate storage policy for object ${WALLET} 2 ${CID} ${H_OID_OTH} ${COPIES} = Get Simple Object Copies ${WALLET} ${CID} ${H_OID}
Should Be Equal As Numbers 2 ${COPIES}
@{S_OBJ_ALL} = Create List ${S_OID} ${H_OID} ${H_OID_OTH} @{S_OBJ_ALL} = Create List ${S_OID} ${H_OID}
@{S_OBJ_H} = Create List ${H_OID} @{S_OBJ_H} = Create List ${H_OID}
@{S_OBJ_H_OTH} = Create List ${H_OID_OTH}
${GET_OBJ_S} = Get object ${WALLET} ${CID} ${S_OID} ${GET_OBJ_S} = Get object ${WALLET} ${CID} ${S_OID}
${GET_OBJ_H} = Get object ${WALLET} ${CID} ${H_OID} ${GET_OBJ_H} = Get object ${WALLET} ${CID} ${H_OID}
@ -59,7 +59,6 @@ NeoFS Simple Object Operations
Search object ${WALLET} ${CID} expected_objects_list=${S_OBJ_ALL} Search object ${WALLET} ${CID} expected_objects_list=${S_OBJ_ALL}
Search object ${WALLET} ${CID} filters=${FILE_USR_HEADER} expected_objects_list=${S_OBJ_H} Search object ${WALLET} ${CID} filters=${FILE_USR_HEADER} expected_objects_list=${S_OBJ_H}
Search object ${WALLET} ${CID} filters=${FILE_USR_HEADER_OTH} expected_objects_list=${S_OBJ_H_OTH}
Head object ${WALLET} ${CID} ${S_OID} Head object ${WALLET} ${CID} ${S_OID}
&{RESPONSE} = Head object ${WALLET} ${CID} ${H_OID} &{RESPONSE} = Head object ${WALLET} ${CID} ${H_OID}