From 7a214562018663846640b5056dfbb9007abc3aaf Mon Sep 17 00:00:00 2001 From: anastasia prasolova Date: Tue, 15 Mar 2022 14:58:59 +0300 Subject: [PATCH] [#184]: neofs verbs divided from neofs.py; HEAD responses are now proccessed as JSON Signed-off-by: anastasia prasolova --- robot/resources/lib/python/cli_helpers.py | 1 + .../resources/lib/python/json_transformers.py | 113 +++++ robot/resources/lib/python/neofs.py | 434 +++--------------- robot/resources/lib/python/neofs_verbs.py | 297 ++++++++++++ .../lib/robot/common_steps_acl_extended.robot | 9 +- .../acl/acl_basic_private_container.robot | 1 + ...basic_private_container_storagegroup.robot | 13 +- .../acl/acl_basic_public_container.robot | 59 +-- ..._basic_public_container_storagegroup.robot | 13 +- .../acl/acl_basic_readonly_container.robot | 43 +- ...asic_readonly_container_storagegroup.robot | 15 +- .../integration/acl/acl_bearer_allow.robot | 1 + .../acl/acl_bearer_allow_storagegroup.robot | 13 +- .../integration/acl/acl_bearer_compound.robot | 3 +- .../acl/acl_bearer_filter_oid_equal.robot | 3 +- .../acl/acl_bearer_filter_oid_not_equal.robot | 3 +- .../acl_bearer_filter_userheader_equal.robot | 3 +- ...l_bearer_filter_userheader_not_equal.robot | 3 +- .../acl/acl_bearer_inaccessible.robot | 1 + ...l_bearer_request_filter_xheader_deny.robot | 1 + ..._bearer_request_filter_xheader_equal.robot | 5 +- ...rer_request_filter_xheader_not_equal.robot | 3 +- .../acl/acl_extended_actions_other.robot | 6 +- .../acl/acl_extended_actions_pubkey.robot | 1 + .../acl/acl_extended_actions_system.robot | 3 +- .../acl/acl_extended_actions_user.robot | 2 +- .../acl/acl_extended_compound.robot | 1 + .../acl/acl_extended_deny_replication.robot | 1 + .../acl/acl_extended_filters.robot | 19 +- .../container_id_filter.robot | 4 +- .../container/container_attributes.robot | 11 +- .../container/container_delete.robot | 8 +- .../network/netmap_control_drop.robot | 5 +- .../integration/network/netmap_simple.robot | 3 +- .../integration/network/replication.robot | 9 +- .../object/object_attributes.robot | 3 +- .../integration/object/object_complex.robot | 1 + .../object/object_expiration.robot | 9 +- .../integration/object/object_simple.robot | 3 +- .../object/object_storagegroup_complex.robot | 10 +- .../object/object_storagegroup_simple.robot | 6 +- .../integration/services/http_gate.robot | 17 +- .../integration/services/s3_gate_object.robot | 2 + 43 files changed, 667 insertions(+), 494 deletions(-) create mode 100644 robot/resources/lib/python/json_transformers.py create mode 100644 robot/resources/lib/python/neofs_verbs.py diff --git a/robot/resources/lib/python/cli_helpers.py b/robot/resources/lib/python/cli_helpers.py index ef604f1d..e34c80a4 100644 --- a/robot/resources/lib/python/cli_helpers.py +++ b/robot/resources/lib/python/cli_helpers.py @@ -19,6 +19,7 @@ def _cmd_run(cmd, timeout=30): in case of failure returns error message. """ try: + logger.info(f"Executing command: {cmd}") compl_proc = subprocess.run(cmd, check=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=timeout, shell=True) diff --git a/robot/resources/lib/python/json_transformers.py b/robot/resources/lib/python/json_transformers.py new file mode 100644 index 00000000..b3895537 --- /dev/null +++ b/robot/resources/lib/python/json_transformers.py @@ -0,0 +1,113 @@ +#!/usr/bin/python3 + +''' + When doing requests to NeoFS, we get JSON output as an automatically decoded + structure from protobuf. Some fields are decoded with boilerplates and binary + values are Base64-encoded. + + This module contains functions which rearrange the structure and reencode binary + data from Base64 to Base58. +''' + + +import base64 +import base58 + +ROBOT_AUTO_KEYWORDS = False + +def decode_simple_header(data: dict): + ''' + This function reencodes Simple Object header and its attributes. + ''' + try: + data = decode_common_fields(data) + + # object attributes view normalization + ugly_attrs = data["header"]["attributes"] + data["header"]["attributes"] = {} + for attr in ugly_attrs: + data["header"]["attributes"][attr["key"]] = attr["value"] + except Exception as exc: + raise ValueError(f"failed to decode JSON output: {exc}") from exc + + return data + + +def decode_split_header(data: dict): + ''' + This function rearranges Complex Object header. + The header holds SplitID, a random unique + number, which is common among all splitted objects, and IDs of the Linking + Object and the last splitted Object. + ''' + try: + data["splitId"] = json_reencode(data["splitId"]) + data["lastPart"] = json_reencode(data["lastPart"]["value"]) + data["link"] = json_reencode(data["link"]["value"]) + except Exception as exc: + raise ValueError(f"failed to decode JSON output: {exc}") from exc + + return data + +def decode_linking_object(data: dict): + ''' + This function reencodes Linking Object header. + It contains IDs of child Objects and Split Chain data. + ''' + try: + data = decode_simple_header(data) + # reencoding Child Object IDs + # { 'value': } -> + for ind, val in enumerate(data['header']['split']['children']): + data['header']['split']['children'][ind] = json_reencode(val['value']) + data['header']['split']['splitID'] = json_reencode(data['header']['split']['splitID']) + data['header']['split']['previous'] = ( + json_reencode(data['header']['split']['previous']['value']) + if data['header']['split']['previous'] else None + ) + data['header']['split']['parent'] = ( + json_reencode(data['header']['split']['parent']['value']) + if data['header']['split']['parent'] else None + ) + except Exception as exc: + raise ValueError(f"failed to decode JSON output: {exc}") from exc + + return data + + +def decode_storage_group(data: dict): + ''' + This function reencodes Storage Group header. + ''' + try: + data = decode_common_fields(data) + except Exception as exc: + raise ValueError(f"failed to decode JSON output: {exc}") from exc + + return data + +def json_reencode(data: str): + ''' + According to JSON protocol, binary data (Object/Container/Storage Group IDs, etc) + is converted to string via Base58 encoder. But we usually operate with Base64-encoded + format. + This function reencodes given Base58 string into the Base64 one. + ''' + return base58.b58encode(base64.b64decode(data)).decode("utf-8") + +def decode_common_fields(data: dict): + ''' + Despite of type (simple/complex Object, Storage Group, etc) every Object + header contains several common fields. + This function rearranges these fields. + ''' + # reencoding binary IDs + data["objectID"] = json_reencode(data["objectID"]["value"]) + data["header"]["containerID"] = json_reencode(data["header"]["containerID"]["value"]) + data["header"]["ownerID"] = json_reencode(data["header"]["ownerID"]["value"]) + data["header"]["homomorphicHash"] = json_reencode(data["header"]["homomorphicHash"]["sum"]) + data["header"]["payloadHash"] = json_reencode(data["header"]["payloadHash"]["sum"]) + data["header"]["version"] = ( + f"{data['header']['version']['major']}{data['header']['version']['minor']}" + ) + return data diff --git a/robot/resources/lib/python/neofs.py b/robot/resources/lib/python/neofs.py index 99bd3521..3108f112 100644 --- a/robot/resources/lib/python/neofs.py +++ b/robot/resources/lib/python/neofs.py @@ -1,7 +1,6 @@ -#!/usr/bin/python3.8 +#!/usr/bin/python3 import base64 -import binascii from datetime import datetime import hashlib import json @@ -11,13 +10,15 @@ import random import uuid import docker import base58 -from functools import reduce from neo3 import wallet from common import * from robot.api.deco import keyword from robot.api import logger + from cli_helpers import _run_with_passwd, _cmd_run +import neofs_verbs +import json_transformers ROBOT_AUTO_KEYWORDS = False @@ -67,7 +68,7 @@ def get_nodes_with_object(private_key: str, cid: str, oid: str): for node in NEOFS_NETMAP: search_res = _search_object(node, private_key, cid, oid) if search_res: - if re.search(fr'({oid})', search_res): + if oid in search_res: nodes_list.append(node) logger.info(f"Nodes with object: {nodes_list}") @@ -98,11 +99,12 @@ def validate_storage_policy_for_object(private_key: str, expected_copies: int, c storage_nodes = storage_nodes if len(storage_nodes) != 0 else NEOFS_NETMAP copies = 0 found_nodes = [] + oid = oid.strip() for node in storage_nodes: search_res = _search_object(node, private_key, cid, oid) if search_res: - if re.search(fr'({oid})', search_res): + if oid in search_res: copies += 1 found_nodes.append(node) @@ -121,21 +123,6 @@ def validate_storage_policy_for_object(private_key: str, expected_copies: int, c raise Exception(f"Found node list '{found_nodes}' is not equal to expected list '{expected_node_list}'") -@keyword('Get Range') -def get_range(private_key: str, cid: str, oid: str, range_file: str, bearer: str, - range_cut: str, options:str=""): - bearer_token = "" - if bearer: - bearer_token = f"--bearer {bearer}" - - Cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {private_key} ' - f'object range --cid {cid} --oid {oid} {bearer_token} --range {range_cut} ' - f'--file {ASSETS_DIR}/{range_file} {options}' - ) - logger.info(f"Cmd: {Cmd}") - _cmd_run(Cmd) - @keyword('Create container') def create_container(private_key: str, basic_acl:str, rule:str, user_headers: str='', session: str=''): @@ -187,39 +174,6 @@ def container_existing(private_key: str, cid: str): return -@keyword('Search object') -def search_object(private_key: str, cid: str, keys: str="", bearer: str="", filters: dict={}, - expected_objects_list=[], options:str=""): - bearer_token = "" - filters_result = "" - - if bearer: - bearer_token = f"--bearer {bearer}" - if filters: - filters_result += "--filters " - logger.info(filters) - for k, v in filters.items(): - filters_result += f"'{k} EQ {v}' " - - object_cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {private_key} ' - f'object search {keys} --cid {cid} {bearer_token} {filters_result} {options}' - ) - logger.info(f"Cmd: {object_cmd}") - output = _cmd_run(object_cmd) - - found_objects = re.findall(r'(\w{43,44})', output) - - if expected_objects_list: - if sorted(found_objects) == sorted(expected_objects_list): - logger.info(f"Found objects list '{found_objects}' ", - f"is equal for expected list '{expected_objects_list}'") - else: - raise Exception(f"Found object list {found_objects} ", - f"is not equal to expected list '{expected_objects_list}'") - - return found_objects - @keyword('Get Split objects') def get_component_objects(private_key: str, cid: str, oid: str): @@ -227,36 +181,36 @@ def get_component_objects(private_key: str, cid: str, oid: str): split_id = "" for node in NEOFS_NETMAP: try: - header_virtual = head_object(private_key, cid, oid, options=' --ttl 1', + parsed_header_virtual = neofs_verbs.head_object(private_key, cid, oid, options=' --ttl 1', endpoint=node, is_raw=True) - if header_virtual: - parsed_header_virtual = parse_object_virtual_raw_header(header_virtual) - if 'Linking object' in parsed_header_virtual.keys(): - return _collect_split_objects_from_header(private_key, cid, parsed_header_virtual) + if 'link' in parsed_header_virtual.keys(): + return _collect_split_objects_from_header(private_key, cid, parsed_header_virtual) - elif 'Split ID' in parsed_header_virtual.keys(): - logger.info(f"parsed_header_virtual: !@ {parsed_header_virtual}" ) - split_id = parsed_header_virtual['Split ID'] + 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 = search_object(private_key, cid, None, None, None, None, '--phy') + 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 = head_object(private_key, cid, targer_oid, is_raw=True) - 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) + 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 = head_object(private_key, cid, parsed_header['Linking object'], is_raw=True) - return header_link_parsed['Split ChildID'] + header_link_parsed = neofs_verbs.head_object(private_key, cid, parsed_header['link']) + return header_link_parsed['header']['split']['children'] @keyword('Verify Split Chain') @@ -274,19 +228,18 @@ def verify_split_chain(wif: str, cid: str, oid: str): logger.info("Collect Split objects information and verify chain of the objects.") for node in NEOFS_NETMAP: try: - header_virtual = head_object(wif, cid, oid, options=' --ttl 1', - endpoint=node, json_output=False, is_raw=True) - parsed_header_virtual = parse_object_virtual_raw_header(header_virtual) + 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 'Last object' in parsed_header_virtual.keys(): - header_last = head_object(wif, cid, - parsed_header_virtual['Last object'], - is_raw=True, json_output=False) - header_last_parsed = _get_raw_split_information(header_last) + 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, final_verif_data) + 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") @@ -302,41 +255,39 @@ def verify_split_chain(wif: str, cid: str, oid: str): logger.info("Compare Split objects result information with Linking object.") for node in NEOFS_NETMAP: try: - header_virtual = head_object(wif, cid, oid, options=' --ttl 1', - endpoint=node, json_output=False, is_raw=True) - parsed_header_virtual = parse_object_virtual_raw_header(header_virtual) - if 'Linking object' in parsed_header_virtual.keys(): - header_link = head_object(wif, cid, - parsed_header_virtual['Linking object'], - is_raw=True, json_output=False) - header_link_parsed = _get_raw_split_information(header_link) + 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['ID List'][::-1] + reversed_list = final_verif_data['header']['split']['children'][::-1] - if header_link_parsed['Split ChildID'] == reversed_list: + 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['Split ChildID'])}") + f"{', '.join(header_link_parsed['header']['split']['children'])}") else: raise Exception(f"Split objects list from Linking Object " - f"({', '.join(header_link_parsed['Split ChildID'])}) " + f"({', '.join(header_link_parsed['header']['split']['children'])}) " f"is not equal to expected ({', '.join(reversed_list)})") - if int(header_link_parsed['PayloadLength']) == 0: + 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['Type'] == 'regular': + 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['Split ID'] == final_verif_data['Split ID']: - logger.info(f"Linking Object Split ID is equal to expected {final_verif_data['Split ID']}.") + 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['Split ID']}) " - f"is not equal to expected ({final_verif_data['Split ID']})") + 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}") @@ -351,100 +302,47 @@ def verify_split_chain(wif: str, cid: str, oid: str): logger.info("Compare Split objects result information with Virtual object.") - header_virtual = head_object(wif, cid, oid, json_output=False) - header_virtual_parsed = _get_raw_split_information(header_virtual) + header_virtual_parsed = neofs_verbs.head_object(wif, cid, oid) - if int(header_virtual_parsed['PayloadLength']) == int(final_verif_data['PayloadLength']): + 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['PayloadLength']}") + f"{header_virtual_parsed['header']['payloadLength']}") else: raise Exception(f"Split objects PayloadLength from Virtual Object " - f"({header_virtual_parsed['PayloadLength']}) is not equal " - f"to expected ({final_verif_data['PayloadLength']})") + f"({header_virtual_parsed['header']['payloadLength']}) is not equal " + f"to expected ({final_verif_data['payloadLength']})") - if header_link_parsed['Type'] == 'regular': + 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 _get_raw_split_information(header): - result_header = dict() - - # Header - Constant attributes - - # ID - m = re.search(r'^ID: (\w+)', header) - if m is not None: - result_header['ID'] = m.group(1) - else: - raise Exception(f"no ID was parsed from object header: \t{header}") - - # Type - m = re.search(r'Type:\s+(\w+)', header) - if m is not None: - result_header['Type'] = m.group(1) - else: - raise Exception(f"no Type was parsed from object header: \t{header}") - - # PayloadLength - m = re.search(r'Size: (\d+)', header) - if m is not None: - result_header['PayloadLength'] = m.group(1) - else: - raise Exception(f"no PayloadLength was parsed from object header: \t{header}") - - # Header - Optional attributes - - # SplitID - m = re.search(r'Split ID:\s+([\w-]+)', header) - if m is not None: - result_header['Split ID'] = m.group(1) - - # Split PreviousID - m = re.search(r'Split PreviousID:\s+(\w+)', header) - if m is not None: - result_header['Split PreviousID'] = m.group(1) - - # Split ParentID - m = re.search(r'Split ParentID:\s+(\w+)', header) - 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) - if found_objects: - result_header['Split ChildID'] = found_objects - logger.info(f"Result: {result_header}") - - return result_header - - 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']) + 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']) + final_verif_data['payloadLength'] = int(header_last_parsed['payloadLength']) - if header_last_parsed['Type'] != 'regular': + if header_last_parsed['objectType'] != 'REGULAR': raise Exception("Object Type is not 'regular'.") - if 'Split ID' in final_verif_data.keys(): - if final_verif_data['Split ID'] != header_last_parsed['Split ID']: - raise Exception(f"Object Split ID ({header_last_parsed['Split ID']}) is not expected ({final_verif_data['Split ID']}).") + 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 ID'] = header_last_parsed['Split ID'] + final_verif_data['split']['splitID'] = header_last_parsed['split']['splitID'] - if 'ID List' in final_verif_data.keys(): - final_verif_data['ID List'].append(header_last_parsed['ID']) + if 'children' in final_verif_data['split'].keys(): + final_verif_data['split']['children'].append(header_last_parsed['split']['children']) else: - final_verif_data['ID List'] = [] - final_verif_data['ID List'].append(header_last_parsed['ID']) + final_verif_data['split']['children'] = [] + final_verif_data['split']['children'].append(header_last_parsed['split']['children']) - if 'Split PreviousID' in header_last_parsed.keys(): - header_virtual = head_object(wif, cid, header_last_parsed['Split PreviousID'], is_raw=True, json_output=False) - parsed_header_virtual = _get_raw_split_information(header_virtual) + 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: @@ -455,9 +353,10 @@ def _verify_child_link(wif: str, cid: str, oid: str, header_last_parsed: dict, f @keyword('Verify Head Tombstone') def verify_head_tombstone(private_key: str, cid: str, oid_ts: str, oid: str, addr: str): + # TODO: replace with HEAD from neofs_verbs.py object_cmd = ( f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {private_key} ' - f'object head --cid {cid} --oid {oid_ts} --json --no-progress' + f'object head --cid {cid} --oid {oid_ts} --json' ) logger.info(f"Cmd: {object_cmd}") output = _cmd_run(object_cmd) @@ -466,13 +365,13 @@ def verify_head_tombstone(private_key: str, cid: str, oid_ts: str, oid: str, add # Header verification header_cid = full_headers["header"]["containerID"]["value"] - if (_json_cli_decode(header_cid) == cid): + if (json_transformers.json_reencode(header_cid) == cid): logger.info(f"Header CID is expected: {cid} ({header_cid} in the output)") else: raise Exception("Header CID is not expected.") header_owner = full_headers["header"]["ownerID"]["value"] - if (_json_cli_decode(header_owner) == addr): + if (json_transformers.json_reencode(header_owner) == addr): logger.info(f"Header ownerID is expected: {addr} ({header_owner} in the output)") else: raise Exception("Header ownerID is not expected.") @@ -490,79 +389,18 @@ def verify_head_tombstone(private_key: str, cid: str, oid_ts: str, oid: str, add raise Exception("Header Session Type is not expected.") header_session_cid = full_headers["header"]["sessionToken"]["body"]["object"]["address"]["containerID"]["value"] - if (_json_cli_decode(header_session_cid) == cid): + if (json_transformers.json_reencode(header_session_cid) == cid): logger.info(f"Header ownerID is expected: {addr} ({header_session_cid} in the output)") else: raise Exception("Header Session CID is not expected.") header_session_oid = full_headers["header"]["sessionToken"]["body"]["object"]["address"]["objectID"]["value"] - if (_json_cli_decode(header_session_oid) == oid): + if (json_transformers.json_reencode(header_session_oid) == oid): logger.info(f"Header Session OID (deleted object) is expected: {oid} ({header_session_oid} in the output)") else: raise Exception("Header Session OID (deleted object) is not expected.") -def _json_cli_decode(data: str): - return base58.b58encode(base64.b64decode(data)).decode("utf-8") - -@keyword('Head object') -def head_object(private_key: str, cid: str, oid: str, bearer_token: str="", - options:str="", endpoint: str="", json_output: bool = True, - is_raw: bool = False): - - cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {endpoint if endpoint else NEOFS_ENDPOINT} ' - f'--wallet {private_key} ' - f'object head --cid {cid} --oid {oid} {options} ' - f'{"--bearer " + bearer_token if bearer_token else ""} ' - f'{"--json" if json_output else ""} ' - f'{"--raw" if is_raw else ""}' - ) - logger.info(f"cmd: {cmd}") - output = _cmd_run(cmd) - - if json_output: - decoded = json.loads(output) - output = _decode_json_output(decoded) - - return output - - -def _decode_json_output(data: dict): - ''' - We get JSON output as an automatically decoded structure from - protobuf. Some fields are decoded with boilerplates and binary - values are Base64-encoded. - - This function rearranges the structure and reencodes binary - data from Base64 to Base58. - - Args: - data (dict): a dictionary which neofs-cli returns to reencode. - - Returns: - dict: dictionary which contains data in a more organized form. - ''' - try: - # reencoding binary IDs - data["objectID"] = _json_cli_decode(data["objectID"]["value"]) - data["header"]["containerID"] = _json_cli_decode(data["header"]["containerID"]["value"]) - data["header"]["ownerID"] = _json_cli_decode(data["header"]["ownerID"]["value"]) - data["header"]["homomorphicHash"] = _json_cli_decode(data["header"]["homomorphicHash"]["sum"]) - data["header"]["payloadHash"] = _json_cli_decode(data["header"]["payloadHash"]["sum"]) - data["header"]["version"] = f"{data['header']['version']['major']}{data['header']['version']['minor']}" - - # object attributes view normalization - ugly_attrs = data["header"]["attributes"] - data["header"]["attributes"] = {} - for attr in ugly_attrs: - data["header"]["attributes"][attr["key"]] = attr["value"] - except Exception as exc: - raise RuntimeError(f"failed to decode JSON output: {exc}") from exc - - return data - - @keyword('Get container attributes') def get_container_attributes(private_key: str, cid: str, endpoint: str="", json_output: bool = False): @@ -577,28 +415,6 @@ def get_container_attributes(private_key: str, cid: str, endpoint: str="", json_ output = _cmd_run(container_cmd) return output -# TODO: replace with JSON parser when https://github.com/nspcc-dev/neofs-node/issues/1233 -# is done -@keyword('Parse Object Virtual Raw Header') -def parse_object_virtual_raw_header(header: str): - result_header = dict() - 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) - - m = re.search(r'Linking object:\s+(\w+)', header) - if m != None: - if m.start() != m.end(): # e.g., if match found something - result_header['Linking object'] = m.group(1) - - m = re.search(r'Last object:\s+(\w+)', header) - if m != None: - if m.start() != m.end(): # e.g., if match found something - result_header['Last object'] = m.group(1) - - logger.info(f"Result: {result_header}") - @keyword('Decode Container Attributes Json') def decode_container_attributes_json(header): @@ -619,22 +435,6 @@ def decode_container_attributes_json(header): return result_header -@keyword('Delete object') -def delete_object(private_key: str, cid: str, oid: str, bearer: str="", options: str=""): - bearer_token = "" - if bearer: - bearer_token = f"--bearer {bearer}" - - object_cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {private_key} ' - f'object delete --cid {cid} --oid {oid} {bearer_token} {options}' - ) - logger.info(f"Cmd: {object_cmd}") - output = _cmd_run(object_cmd) - tombstone = _parse_oid(output) - - return tombstone - @keyword('Delete Container') # TODO: make the error message about a non-found container more user-friendly https://github.com/nspcc-dev/neofs-contract/issues/121 @@ -654,41 +454,6 @@ def get_file_hash(filename : str): return file_hash -@keyword('Put object') -def put_object(private_key: str, path: str, cid: str, bearer: str="", user_headers: dict={}, - endpoint: str="", options: str="" ): - if not endpoint: - endpoint = random.sample(NEOFS_NETMAP, 1)[0] - - if bearer: - bearer = f"--bearer {bearer}" - - putobject_cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {endpoint} --wallet {private_key} object ' - f'put --no-progress --file {path} --cid {cid} {bearer} {options} ' - f'{"--attributes " + _dict_to_attrs(user_headers) if user_headers else ""}' - ) - logger.info(f"cmd: {putobject_cmd}") - output = _cmd_run(putobject_cmd) - oid = _parse_oid(output) - return oid - - -def _dict_to_attrs(attrs: dict): - ''' - This function takes dictionary of object attributes and converts them - into the string. The string is passed to `--attibutes` key of the - neofs-cli. - - Args: - attrs (dict): object attirbutes in {"a": "b", "c": "d"} format. - - Returns: - (str): string in "a=b,c=d" format. - ''' - return reduce(lambda a,b: f"{a},{b}", map(lambda i: f"{i}={attrs[i]}", attrs)) - - @keyword('Get control endpoint with wif') def get_control_endpoint_with_wif(endpoint_number: str = ''): if endpoint_number == '': @@ -775,45 +540,6 @@ def find_in_nodes_Log(line: str, nodes_logs_time: dict): return 1 -@keyword('Get Range Hash') -def get_range_hash(private_key: str, cid: str, oid: str, bearer_token: str, - range_cut: str, options: str=""): - if bearer_token: - bearer_token = f"--bearer {bearer_token}" - - object_cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {private_key} ' - f'object hash --cid {cid} --oid {oid} --range {range_cut} ' - f'{bearer_token} {options}' - ) - logger.info(f"Cmd: {object_cmd}") - _cmd_run(object_cmd) - - -@keyword('Get object') -def get_object(private_key: str, cid: str, oid: str, bearer_token: str="", - write_object: str="", endpoint: str="", options: str="" ): - - if not write_object: - write_object = str(uuid.uuid4()) - file_path = f"{ASSETS_DIR}/{write_object}" - - logger.info("Going to get the object") - if not endpoint: - endpoint = random.sample(NEOFS_NETMAP, 1)[0] - - - if bearer_token: - bearer_token = f"--bearer {bearer_token}" - - object_cmd = ( - f'{NEOFS_CLI_EXEC} --rpc-endpoint {endpoint} --wallet {private_key} ' - f'object get --cid {cid} --oid {oid} --file {file_path} {bearer_token} ' - f'{options}' - ) - logger.info(f"Cmd: {object_cmd}") - _cmd_run(object_cmd) - return file_path @@ -1022,20 +748,10 @@ def _parse_cid(input_str: str): def _search_object(node:str, private_key: str, cid:str, oid: str): - if oid: - oid_cmd = "--oid %s" % oid Cmd = ( f'{NEOFS_CLI_EXEC} --rpc-endpoint {node} --wallet {private_key} --ttl 1 ' - f'object search --root --cid {cid} {oid_cmd}' + f'object search --root --cid {cid} --oid {oid}' ) output = _cmd_run(Cmd) - if re.search(fr'{oid}', output): - return oid - else: - logger.info("Object is not found.") - - if re.search(r'local node is outside of object placement', output): - logger.info("Server is not presented in container.") - elif ( re.search(r'timed out after 30 seconds', output) or re.search(r'no route to host', output) or re.search(r'i/o timeout', output)): - logger.warn("Node is unavailable") + return output diff --git a/robot/resources/lib/python/neofs_verbs.py b/robot/resources/lib/python/neofs_verbs.py new file mode 100644 index 00000000..92f14cae --- /dev/null +++ b/robot/resources/lib/python/neofs_verbs.py @@ -0,0 +1,297 @@ +#!/usr/bin/python3 + +''' + This module contains wrappers for NeoFS verbs executed via neofs-cli. +''' + +import json +import os +import re +import random +import uuid +from functools import reduce + +from common import NEOFS_ENDPOINT, ASSETS_DIR, NEOFS_NETMAP +from cli_helpers import _cmd_run +import json_transformers + +from robot.api.deco import keyword +from robot.api import logger + +ROBOT_AUTO_KEYWORDS = False + +# path to neofs-cli executable +NEOFS_CLI_EXEC = os.getenv('NEOFS_CLI_EXEC', 'neofs-cli') + + +@keyword('Get object') +def get_object(wif: str, cid: str, oid: str, bearer_token: str="", + write_object: str="", endpoint: str="", options: str="" ): + ''' + GET from NeoFS. + + Args: + wif (str): WIF of the wallet on whose behalf GET is done + cid (str): ID of Container where we get the Object from + oid (str): Object ID + bearer_token (optional, str): path to Bearer Token file, appends to `--bearer` key + write_object (optional, str): path to downloaded file, appends to `--file` key + endpoint (optional, str): NeoFS endpoint to send request to, appends to `--rpc-endpoint` key + options (optional, str): any options which `neofs-cli object get` accepts + Returns: + (str): path to downloaded file + ''' + + if not write_object: + write_object = str(uuid.uuid4()) + file_path = f"{ASSETS_DIR}/{write_object}" + + if not endpoint: + endpoint = random.sample(NEOFS_NETMAP, 1)[0] + + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {endpoint} --wallet {wif} ' + f'object get --cid {cid} --oid {oid} --file {file_path} ' + f'{"--bearer " + bearer_token if bearer_token else ""} ' + f'{options}' + ) + _cmd_run(cmd) + return file_path + + +@keyword('Get Range Hash') +def get_range_hash(wif: str, cid: str, oid: str, bearer_token: str, + range_cut: str, options: str=""): + ''' + GETRANGEHASH of given Object. + + Args: + wif (str): WIF of the wallet on whose behalf GETRANGEHASH is done + cid (str): ID of Container where we get the Object from + oid (str): Object ID + bearer_token (str): path to Bearer Token file, appends to `--bearer` key + range_cut (str): Range to take hash from in the form offset1:length1,..., + value to pass to the `--range` parameter + options (optional, str): any options which `neofs-cli object hash` accepts + Returns: + None + ''' + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wif} ' + f'object hash --cid {cid} --oid {oid} --range {range_cut} ' + f'{"--bearer " + bearer_token if bearer_token else ""} ' + f'{options}' + ) + _cmd_run(cmd) + + +@keyword('Put object') +def put_object(wif: str, path: str, cid: str, bearer: str="", user_headers: dict={}, + endpoint: str="", options: str="" ): + ''' + PUT of given file. + + Args: + wif (str): WIF of the wallet on whose behalf PUT is done + path (str): path to file to be PUT + cid (str): ID of Container where we get the Object from + bearer (optional, str): path to Bearer Token file, appends to `--bearer` key + user_headers (optional, dict): Object attributes, append to `--attributes` key + endpoint(optional, str): NeoFS endpoint to send request to + options (optional, str): any options which `neofs-cli object put` accepts + Returns: + (str): ID of uploaded Object + ''' + if not endpoint: + endpoint = random.sample(NEOFS_NETMAP, 1)[0] + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {endpoint} --wallet {wif} ' + f'object put --file {path} --cid {cid} {options} ' + f'{"--bearer " + bearer if bearer else ""} ' + f'{"--attributes " + _dict_to_attrs(user_headers) if user_headers else ""}' + ) + output = _cmd_run(cmd) + # splitting CLI output to lines and taking the penultimate line + id_str = output.strip().split('\n')[-2] + oid = id_str.split(':')[1] + return oid.strip() + + +@keyword('Delete object') +def delete_object(wif: str, cid: str, oid: str, bearer: str="", options: str=""): + ''' + DELETE an Object. + + Args: + wif (str): WIF of the wallet on whose behalf DELETE is done + cid (str): ID of Container where we get the Object from + oid (str): ID of Object we are going to delete + bearer (optional, str): path to Bearer Token file, appends to `--bearer` key + options (optional, str): any options which `neofs-cli object delete` accepts + Returns: + (str): Tombstone ID + ''' + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wif} ' + f'object delete --cid {cid} --oid {oid} {options}' + f'{"--bearer " + bearer if bearer else ""} ' + ) + output = _cmd_run(cmd) + id_str = output.split('\n')[1] + tombstone = id_str.split(':')[1] + return tombstone.strip() + + +@keyword('Get Range') +def get_range(wif: str, cid: str, oid: str, range_file: str, bearer: str, + range_cut: str, options:str=""): + ''' + GETRANGE an Object. + + Args: + wif (str): WIF of the wallet on whose behalf GETRANGE is done + cid (str): ID of Container where we get the Object from + oid (str): ID of Object we are going to request + range_file (str): file where payload range data will be written + bearer (str): path to Bearer Token file, appends to `--bearer` key + range_cut (str): range to take data from in the form offset:length + options (optional, str): any options which `neofs-cli object range` accepts + Returns: + None + ''' + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wif} ' + f'object range --cid {cid} --oid {oid} --range {range_cut} ' + f'--file {ASSETS_DIR}/{range_file} {options}' + f'{"--bearer " + bearer if bearer else ""} ' + ) + _cmd_run(cmd) + + +@keyword('Search object') +def search_object(wif: str, cid: str, keys: str="", bearer: str="", filters: dict={}, + expected_objects_list=[], options:str=""): + ''' + GETRANGE an Object. + + Args: + wif (str): WIF of the wallet on whose behalf SEARCH is done + cid (str): ID of Container where we get the Object from + keys(optional, str): any keys for Object SEARCH which `neofs-cli object search` + accepts, e.g. `--oid` + bearer (optional, str): path to Bearer Token file, appends to `--bearer` key + filters (optional, dict): key=value pairs to filter Objects + expected_objects_list (optional, list): a list of ObjectIDs to compare found Objects with + options (optional, str): any options which `neofs-cli object search` accepts + Returns: + (list): list of found ObjectIDs + ''' + filters_result = "" + if filters: + filters_result += "--filters " + logger.info(filters) + for key, value in filters.items(): + filters_result += f"'{key} EQ {value}' " + + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wif} ' + f'object search {keys} --cid {cid} {filters_result} {options}' + f'{"--bearer " + bearer if bearer else ""} ' + ) + output = _cmd_run(cmd) + + found_objects = re.findall(r'(\w{43,44})', output) + + if expected_objects_list: + if sorted(found_objects) == sorted(expected_objects_list): + logger.info(f"Found objects list '{found_objects}' ", + f"is equal for expected list '{expected_objects_list}'") + else: + raise Exception(f"Found object list {found_objects} ", + f"is not equal to expected list '{expected_objects_list}'") + + return found_objects + + +@keyword('Head object') +def head_object(wif: str, cid: str, oid: str, bearer_token: str="", + options:str="", endpoint: str="", json_output: bool = True, + is_raw: bool = False): + ''' + HEAD an Object. + + Args: + wif (str): WIF of the wallet on whose behalf HEAD is done + cid (str): ID of Container where we get the Object from + oid (str): ObjectID to HEAD + bearer_token (optional, str): path to Bearer Token file, appends to `--bearer` key + options (optional, str): any options which `neofs-cli object head` accepts + endpoint(optional, str): NeoFS endpoint to send request to + json_output(optional, bool): return reponse in JSON format or not; this flag + turns into `--json` key + is_raw(optional, bool): send "raw" request or not; this flag + turns into `--raw` key + Returns: + depending on the `json_output` parameter value, the function returns + (dict): HEAD response in JSON format + or + (str): HEAD response as a plain text + ''' + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {endpoint if endpoint else NEOFS_ENDPOINT} ' + f'--wallet {wif} ' + f'object head --cid {cid} --oid {oid} {options} ' + f'{"--bearer " + bearer_token if bearer_token else ""} ' + f'{"--json" if json_output else ""} ' + f'{"--raw" if is_raw else ""}' + ) + output = _cmd_run(cmd) + + if not json_output: + return output + + decoded = "" + try: + decoded = json.loads(output) + except Exception as exc: + # If we failed to parse output as JSON, the cause might be + # the plain text string in the beginning of the output. + # Here we cut off first string and try to parse again. + logger.info(f"failed to parse output: {exc}") + logger.info("parsing output in another way") + fst_line_idx = output.find('\n') + decoded = json.loads(output[fst_line_idx:]) + + # If response is Complex Object header, it has `splitId` key + if 'splitId' in decoded.keys(): + logger.info("decoding split header") + return json_transformers.decode_split_header(decoded) + + # If response is Last or Linking Object header, + # it has `header` dictionary and non-null `split` dictionary + if 'split' in decoded['header'].keys(): + if decoded['header']['split']: + logger.info("decoding linking object") + return json_transformers.decode_linking_object(decoded) + + if decoded['header']['objectType'] == 'STORAGE_GROUP': + logger.info("decoding storage group") + return json_transformers.decode_storage_group(decoded) + + logger.info("decoding simple header") + return json_transformers.decode_simple_header(decoded) + + +def _dict_to_attrs(attrs: dict): + ''' + This function takes dictionary of object attributes and converts them + into the string. The string is passed to `--attibutes` key of the + neofs-cli. + + Args: + attrs (dict): object attirbutes in {"a": "b", "c": "d"} format. + + Returns: + (str): string in "a=b,c=d" format. + ''' + return reduce(lambda a,b: f"{a},{b}", map(lambda i: f"{i}={attrs[i]}", attrs)) diff --git a/robot/resources/lib/robot/common_steps_acl_extended.robot b/robot/resources/lib/robot/common_steps_acl_extended.robot index a9687896..1c8b9862 100644 --- a/robot/resources/lib/robot/common_steps_acl_extended.robot +++ b/robot/resources/lib/robot/common_steps_acl_extended.robot @@ -4,6 +4,7 @@ Variables eacl_object_filters.py Library acl.py Library neofs.py +Library neofs_verbs.py Library Collections Resource common_steps_acl_basic.robot @@ -91,7 +92,7 @@ Check eACL Deny and Allow All Compose eACL Custom [Arguments] ${CID} ${HEADER_DICT} ${MATCH_TYPE} ${FILTER} ${ACCESS} ${ROLE} - ${filter_value} = Get From dictionary ${HEADER_DICT}[header] ${EACL_OBJ_FILTERS}[${FILTER}] + ${filter_value} = Get From dictionary ${HEADER_DICT} ${EACL_OBJ_FILTERS}[${FILTER}] ${filters} = Set Variable obj:${FILTER}${MATCH_TYPE}${filter_value} ${rule_get}= Set Variable ${ACCESS} get ${filters} ${ROLE} @@ -112,8 +113,12 @@ Object Header Decoded [Arguments] ${USER_KEY} ${CID} ${OID} &{HEADER} = Head Object ${USER_KEY} ${CID} ${OID} + # FIXME + # 'objectID' key repositioning in dictionary for the calling keyword might + # work uniformly with any key from 'header' + Set To Dictionary ${HEADER}[header] objectID ${HEADER}[objectID] - [Return] &{HEADER} + [Return] &{HEADER}[header] Check eACL Filters with MatchType String Equal [Arguments] ${FILTER} diff --git a/robot/testsuites/integration/acl/acl_basic_private_container.robot b/robot/testsuites/integration/acl/acl_basic_private_container.robot index a006da27..3abe1a71 100644 --- a/robot/testsuites/integration/acl/acl_basic_private_container.robot +++ b/robot/testsuites/integration/acl/acl_basic_private_container.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource common_steps_acl_basic.robot diff --git a/robot/testsuites/integration/acl/acl_basic_private_container_storagegroup.robot b/robot/testsuites/integration/acl/acl_basic_private_container_storagegroup.robot index 8391f235..1026608f 100644 --- a/robot/testsuites/integration/acl/acl_basic_private_container_storagegroup.robot +++ b/robot/testsuites/integration/acl/acl_basic_private_container_storagegroup.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library Collections @@ -13,20 +14,20 @@ Resource setup_teardown.robot *** Test cases *** Basic ACL Operations for Private Container [Documentation] Testcase to validate NeoFS operations with ACL for Private Container. - [Tags] ACL NeoFS NeoCLI + [Tags] ACL [Timeout] 20 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${OTHER_KEY} = Prepare Wallet And Deposit ${PRIV_CID} = Create Private Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${SIMPLE_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${SIMPLE_OBJ_SIZE} Check Private Container Simple ${USER_KEY} ${FILE_S} ${PRIV_CID} ${OTHER_KEY} ${PRIV_CID} = Create Private Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${COMPLEX_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${COMPLEX_OBJ_SIZE} Check Private Container Complex ${USER_KEY} ${FILE_S} ${PRIV_CID} ${OTHER_KEY} [Teardown] Teardown acl_basic_private_container_storagegroup @@ -38,7 +39,7 @@ Check Private Container [Arguments] ${RUN_TYPE} ${USER_KEY} ${FILE_S} ${PRIV_CID} ${OTHER_KEY} # Put target object to use in storage groups - ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY} + ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${PRIV_CID} # Storage group Operations (Put, List, Get, Delete) with different Keys diff --git a/robot/testsuites/integration/acl/acl_basic_public_container.robot b/robot/testsuites/integration/acl/acl_basic_public_container.robot index d0e025a1..d05a4dc5 100644 --- a/robot/testsuites/integration/acl/acl_basic_public_container.robot +++ b/robot/testsuites/integration/acl/acl_basic_public_container.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource common_steps_acl_basic.robot @@ -12,20 +13,20 @@ Resource setup_teardown.robot *** Test cases *** Basic ACL Operations for Public Container [Documentation] Testcase to validate NeoFS operations with ACL for Public Container. - [Tags] ACL NeoFS NeoCLI + [Tags] ACL [Timeout] 20 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${OTHER_KEY} = Prepare Wallet And Deposit ${PUBLIC_CID} = Create Public Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${SIMPLE_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${SIMPLE_OBJ_SIZE} Check Public Container ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${OTHER_KEY} ${PUBLIC_CID} = Create Public Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${COMPLEX_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${COMPLEX_OBJ_SIZE} Check Public Container ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${OTHER_KEY} [Teardown] Teardown acl_basic_public_container @@ -37,10 +38,10 @@ Check Public Container [Arguments] ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${OTHER_KEY} # Put - ${S_OID_USER} = Put Object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY} - ${S_OID_OTHER} = Put Object ${OTHER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY} - ${S_OID_SYS_IR} = Put Object ${NEOFS_IR_WIF} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY} - ${S_OID_SYS_SN} = Put Object ${NEOFS_SN_WIF} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY} + ${S_OID_USER} = Put Object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} + ${S_OID_OTHER} = Put Object ${OTHER_KEY} ${FILE_S} ${PUBLIC_CID} + ${S_OID_SYS_IR} = Put Object ${NEOFS_IR_WIF} ${FILE_S} ${PUBLIC_CID} + ${S_OID_SYS_SN} = Put Object ${NEOFS_SN_WIF} ${FILE_S} ${PUBLIC_CID} # Get Get Object ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} s_file_read @@ -65,32 +66,32 @@ Check Public Container # 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} --root ${EMPTY} ${EMPTY} ${S_OBJ_PRIV} - Search object ${OTHER_KEY} ${PUBLIC_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_PRIV} - Search object ${NEOFS_IR_WIF} ${PUBLIC_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_PRIV} - Search object ${NEOFS_SN_WIF} ${PUBLIC_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_PRIV} + Search object ${USER_KEY} ${PUBLIC_CID} keys=--root expected_objects_list=${S_OBJ_PRIV} + Search object ${OTHER_KEY} ${PUBLIC_CID} keys=--root expected_objects_list=${S_OBJ_PRIV} + Search object ${NEOFS_IR_WIF} ${PUBLIC_CID} keys=--root expected_objects_list=${S_OBJ_PRIV} + Search object ${NEOFS_SN_WIF} ${PUBLIC_CID} keys=--root expected_objects_list=${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 ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} ${EMPTY} - Head Object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} ${EMPTY} + Head Object ${USER_KEY} ${PUBLIC_CID} ${S_OID_USER} + Head Object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_USER} + Head Object ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_USER} + Head Object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_USER} - Head Object ${USER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY} - Head Object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY} - Head Object ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY} - Head Object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} ${EMPTY} + Head Object ${USER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} + Head Object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_OTHER} + Head Object ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_OTHER} + Head Object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_OTHER} - 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 ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} ${EMPTY} - Head Object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} ${EMPTY} + Head Object ${USER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} + Head Object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} + Head Object ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_SYS_SN} + Head Object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_SYS_SN} # Delete - Delete object ${USER_KEY} ${PUBLIC_CID} ${S_OID_SYS_IR} ${EMPTY} - Delete Object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} ${EMPTY} + Delete object ${USER_KEY} ${PUBLIC_CID} ${S_OID_SYS_IR} + Delete Object ${OTHER_KEY} ${PUBLIC_CID} ${S_OID_SYS_SN} Run Keyword And Expect Error * - ... Delete object ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_USER} ${EMPTY} + ... Delete object ${NEOFS_IR_WIF} ${PUBLIC_CID} ${S_OID_USER} Run Keyword And Expect Error * - ... Delete object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY} + ... Delete object ${NEOFS_SN_WIF} ${PUBLIC_CID} ${S_OID_OTHER} diff --git a/robot/testsuites/integration/acl/acl_basic_public_container_storagegroup.robot b/robot/testsuites/integration/acl/acl_basic_public_container_storagegroup.robot index 0c30a0bd..1a0903df 100644 --- a/robot/testsuites/integration/acl/acl_basic_public_container_storagegroup.robot +++ b/robot/testsuites/integration/acl/acl_basic_public_container_storagegroup.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library contract_keywords.py @@ -13,20 +14,20 @@ Resource setup_teardown.robot *** Test cases *** Basic ACL Operations for Public Container [Documentation] Testcase to validate NeoFS operations with ACL for Public Container. - [Tags] ACL NeoFS NeoCLI + [Tags] ACL [Timeout] 20 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${OTHER_KEY} = Prepare Wallet And Deposit ${PUBLIC_CID} = Create Public Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${SIMPLE_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${SIMPLE_OBJ_SIZE} Check Public Container Simple ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${OTHER_KEY} ${PUBLIC_CID} = Create Public Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${COMPLEX_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${COMPLEX_OBJ_SIZE} Check Public Container Complex ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${OTHER_KEY} [Teardown] Teardown acl_basic_public_container_storagegroup @@ -41,7 +42,7 @@ Check Public Container Log Storage group Operations for each Role keys # Put target object to use in storage groups - ${S_OID} = Put object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY} + ${S_OID} = Put object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} @{ROLES_KEYS_PASS} = Create List ${USER_KEY} ${OTHER_KEY} @{ROLES_KEYS_SYS} = Create List ${NEOFS_IR_WIF} ${NEOFS_SN_WIF} diff --git a/robot/testsuites/integration/acl/acl_basic_readonly_container.robot b/robot/testsuites/integration/acl/acl_basic_readonly_container.robot index cd0c5531..5ca6a1a2 100644 --- a/robot/testsuites/integration/acl/acl_basic_readonly_container.robot +++ b/robot/testsuites/integration/acl/acl_basic_readonly_container.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource common_steps_acl_basic.robot @@ -12,20 +13,20 @@ Resource setup_teardown.robot *** Test cases *** Basic ACL Operations for Read-Only Container [Documentation] Testcase to validate NeoFS operations with ACL for Read-Only Container. - [Tags] ACL NeoFS NeoCLI + [Tags] ACL [Timeout] 20 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${OTHER_KEY} = Prepare Wallet And Deposit ${READONLY_CID} = Create Read-Only Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${SIMPLE_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${SIMPLE_OBJ_SIZE} Check Read-Only Container Simple ${USER_KEY} ${FILE_S} ${READONLY_CID} ${OTHER_KEY} ${READONLY_CID} = Create Read-Only Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${COMPLEX_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${COMPLEX_OBJ_SIZE} Check Read-Only Container Complex ${USER_KEY} ${FILE_S} ${READONLY_CID} ${OTHER_KEY} [Teardown] Teardown acl_basic_readonly_container @@ -38,11 +39,11 @@ Check Read-Only Container [Arguments] ${RUN_TYPE} ${USER_KEY} ${FILE_S} ${READONLY_CID} ${OTHER_KEY} # Put - ${S_OID_USER} = Put Object ${USER_KEY} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY} + ${S_OID_USER} = Put Object ${USER_KEY} ${FILE_S} ${READONLY_CID} Run Keyword And Expect Error * - ... Put object ${OTHER_KEY} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY} - ${S_OID_SYS_IR} = Put Object ${NEOFS_IR_WIF} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY} - ${S_OID_SYS_SN} = Put object ${NEOFS_SN_WIF} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY} + ... Put object ${OTHER_KEY} ${FILE_S} ${READONLY_CID} + ${S_OID_SYS_IR} = Put Object ${NEOFS_IR_WIF} ${FILE_S} ${READONLY_CID} + ${S_OID_SYS_SN} = Put object ${NEOFS_SN_WIF} ${FILE_S} ${READONLY_CID} # Storage group Operations (Put, List, Get, Delete) @@ -94,23 +95,23 @@ Check Read-Only Container # Search @{S_OBJ_RO} = Create List ${S_OID_USER} ${S_OID_SYS_SN} ${S_OID_SYS_IR} - Search Object ${USER_KEY} ${READONLY_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_RO} - Search Object ${OTHER_KEY} ${READONLY_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_RO} - Search Object ${NEOFS_IR_WIF} ${READONLY_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_RO} - Search Object ${NEOFS_SN_WIF} ${READONLY_CID} --root ${EMPTY} ${EMPTY} ${S_OBJ_RO} + Search Object ${USER_KEY} ${READONLY_CID} keys=--root expected_objects_list=${S_OBJ_RO} + Search Object ${OTHER_KEY} ${READONLY_CID} keys=--root expected_objects_list=${S_OBJ_RO} + Search Object ${NEOFS_IR_WIF} ${READONLY_CID} keys=--root expected_objects_list=${S_OBJ_RO} + Search Object ${NEOFS_SN_WIF} ${READONLY_CID} keys=--root expected_objects_list=${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 ${NEOFS_IR_WIF} ${READONLY_CID} ${S_OID_USER} ${EMPTY} ${EMPTY} - Head Object ${NEOFS_SN_WIF} ${READONLY_CID} ${S_OID_USER} ${EMPTY} ${EMPTY} + Head Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} + Head Object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} + Head Object ${NEOFS_IR_WIF} ${READONLY_CID} ${S_OID_USER} + Head Object ${NEOFS_SN_WIF} ${READONLY_CID} ${S_OID_USER} # Delete Run Keyword And Expect Error * - ... Delete object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} + ... Delete object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} Run Keyword And Expect Error * - ... Delete object ${NEOFS_IR_WIF} ${READONLY_CID} ${S_OID_USER} ${EMPTY} + ... Delete object ${NEOFS_IR_WIF} ${READONLY_CID} ${S_OID_USER} Run Keyword And Expect Error * - ... Delete object ${NEOFS_SN_WIF} ${READONLY_CID} ${S_OID_USER} ${EMPTY} - Delete Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} + ... Delete object ${NEOFS_SN_WIF} ${READONLY_CID} ${S_OID_USER} + Delete Object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} diff --git a/robot/testsuites/integration/acl/acl_basic_readonly_container_storagegroup.robot b/robot/testsuites/integration/acl/acl_basic_readonly_container_storagegroup.robot index 051c0f05..6badf006 100644 --- a/robot/testsuites/integration/acl/acl_basic_readonly_container_storagegroup.robot +++ b/robot/testsuites/integration/acl/acl_basic_readonly_container_storagegroup.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource common_steps_acl_basic.robot @@ -12,20 +13,20 @@ Resource setup_teardown.robot *** Test cases *** Basic ACL Operations for Read-Only Container [Documentation] Testcase to validate NeoFS operations with ACL for Read-Only Container. - [Tags] ACL NeoFS NeoCLI + [Tags] ACL [Timeout] 20 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit - + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${OTHER_KEY} = Prepare Wallet And Deposit + ${READONLY_CID} = Create Read-Only Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${SIMPLE_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${SIMPLE_OBJ_SIZE} Check Read-Only Container Simple ${USER_KEY} ${FILE_S} ${READONLY_CID} ${OTHER_KEY} ${READONLY_CID} = Create Read-Only Container ${USER_KEY} - ${FILE_S} ${FILE_S_HASH} = Generate file ${COMPLEX_OBJ_SIZE} + ${FILE_S} ${_} = Generate file ${COMPLEX_OBJ_SIZE} Check Read-Only Container Complex ${USER_KEY} ${FILE_S} ${READONLY_CID} ${OTHER_KEY} @@ -39,7 +40,7 @@ Check Read-Only Container [Arguments] ${RUN_TYPE} ${USER_KEY} ${FILE_S} ${READONLY_CID} ${OTHER_KEY} # Put target object to use in storage groups - ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY} + ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${READONLY_CID} # Storage group Operations (Put, List, Get, Delete) for Read-only container diff --git a/robot/testsuites/integration/acl/acl_bearer_allow.robot b/robot/testsuites/integration/acl/acl_bearer_allow.robot index e8c7f024..b033a61b 100644 --- a/robot/testsuites/integration/acl/acl_bearer_allow.robot +++ b/robot/testsuites/integration/acl/acl_bearer_allow.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py diff --git a/robot/testsuites/integration/acl/acl_bearer_allow_storagegroup.robot b/robot/testsuites/integration/acl/acl_bearer_allow_storagegroup.robot index ea558c26..c1e8dd00 100644 --- a/robot/testsuites/integration/acl/acl_bearer_allow_storagegroup.robot +++ b/robot/testsuites/integration/acl/acl_bearer_allow_storagegroup.robot @@ -4,6 +4,7 @@ Variables common.py Library Collections Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource eacl_tables.robot @@ -15,13 +16,13 @@ Resource setup_teardown.robot *** Test cases *** BearerToken Operations [Documentation] Testcase to validate NeoFS operations with BearerToken. - [Tags] ACL NeoFS NeoCLI BearerToken + [Tags] ACL BearerToken [Timeout] 20 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + Log Check Bearer token with simple object ${FILE_S} = Generate file ${SIMPLE_OBJ_SIZE} Check eACL Deny and Allow All Bearer Simple ${USER_KEY} ${FILE_S} @@ -39,10 +40,10 @@ BearerToken Operations Check eACL Deny and Allow All Bearer [Arguments] ${RUN_TYPE} ${USER_KEY} ${FILE_S} - + ${CID} = Create Container Public ${USER_KEY} - ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER} - Prepare eACL Role rules ${CID} + ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} + Prepare eACL Role rules ${CID} # Storage group Operations (Put, List, Get, Delete) diff --git a/robot/testsuites/integration/acl/acl_bearer_compound.robot b/robot/testsuites/integration/acl/acl_bearer_compound.robot index dbbb1e19..d81c1096 100644 --- a/robot/testsuites/integration/acl/acl_bearer_compound.robot +++ b/robot/testsuites/integration/acl/acl_bearer_compound.robot @@ -4,6 +4,7 @@ Variables common.py Library Collections Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource eacl_tables.robot @@ -59,7 +60,7 @@ Check Bearer Сompound Get ${CID} = Create Container Public ${USER_KEY} Prepare eACL Role rules ${CID} ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} - @{S_OBJ_H} = Create List ${S_OID_USER} + @{S_OBJ_H} = Create List ${S_OID_USER} ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} Put object ${KEY} ${FILE_S} ${CID} user_headers=${ANOTHER_HEADER} diff --git a/robot/testsuites/integration/acl/acl_bearer_filter_oid_equal.robot b/robot/testsuites/integration/acl/acl_bearer_filter_oid_equal.robot index 75284366..3da459f4 100644 --- a/robot/testsuites/integration/acl/acl_bearer_filter_oid_equal.robot +++ b/robot/testsuites/integration/acl/acl_bearer_filter_oid_equal.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py @@ -50,7 +51,7 @@ Check eACL Deny and Allow All Bearer Filter OID Equal ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} ${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} ${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_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} user_headers=${ANOTHER_HEADER} Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl diff --git a/robot/testsuites/integration/acl/acl_bearer_filter_oid_not_equal.robot b/robot/testsuites/integration/acl/acl_bearer_filter_oid_not_equal.robot index 8922473a..0133ed55 100644 --- a/robot/testsuites/integration/acl/acl_bearer_filter_oid_not_equal.robot +++ b/robot/testsuites/integration/acl/acl_bearer_filter_oid_not_equal.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py @@ -47,7 +48,7 @@ Check eACL Deny and Allow All Bearer Filter OID NotEqual ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} ${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} ${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} - @{S_OBJ_H} = Create List ${S_OID_USER} + @{S_OBJ_H} = Create List ${S_OID_USER} Put object ${USER_KEY} ${FILE_S} ${CID} Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl diff --git a/robot/testsuites/integration/acl/acl_bearer_filter_userheader_equal.robot b/robot/testsuites/integration/acl/acl_bearer_filter_userheader_equal.robot index 335b6616..8e75beab 100644 --- a/robot/testsuites/integration/acl/acl_bearer_filter_userheader_equal.robot +++ b/robot/testsuites/integration/acl/acl_bearer_filter_userheader_equal.robot @@ -4,6 +4,7 @@ Variables common.py Library Collections Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource eacl_tables.robot @@ -45,7 +46,7 @@ Check eACL Deny and Allow All Bearer Filter UserHeader Equal ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} ${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} ${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_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} user_headers=${ANOTHER_HEADER} Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl diff --git a/robot/testsuites/integration/acl/acl_bearer_filter_userheader_not_equal.robot b/robot/testsuites/integration/acl/acl_bearer_filter_userheader_not_equal.robot index 975f3475..e0918e5a 100644 --- a/robot/testsuites/integration/acl/acl_bearer_filter_userheader_not_equal.robot +++ b/robot/testsuites/integration/acl/acl_bearer_filter_userheader_not_equal.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py @@ -46,7 +47,7 @@ Check eACL Deny and Allow All Bearer Filter UserHeader NotEqual ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${ANOTHER_HEADER} ${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} ${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER_DEL} - @{S_OBJ_H} = Create List ${S_OID_USER_2} + @{S_OBJ_H} = Create List ${S_OID_USER_2} Put object ${USER_KEY} ${FILE_S} ${CID} Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl diff --git a/robot/testsuites/integration/acl/acl_bearer_inaccessible.robot b/robot/testsuites/integration/acl/acl_bearer_inaccessible.robot index de3d4110..8de94f6a 100644 --- a/robot/testsuites/integration/acl/acl_bearer_inaccessible.robot +++ b/robot/testsuites/integration/acl/acl_bearer_inaccessible.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py diff --git a/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_deny.robot b/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_deny.robot index 4711a1a9..3412081a 100644 --- a/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_deny.robot +++ b/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_deny.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py diff --git a/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_equal.robot b/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_equal.robot index 18bfce16..07db2368 100644 --- a/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_equal.robot +++ b/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_equal.robot @@ -4,6 +4,7 @@ Variables common.py Library Collections Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource eacl_tables.robot @@ -48,7 +49,7 @@ Check eACL Deny and Allow All Bearer Filter Requst Equal ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} ${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} ${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_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} Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl @@ -71,7 +72,7 @@ Check eACL Deny and Allow All Bearer Filter Requst Equal ${rule6}= Create Dictionary Operation=GETRANGE Access=ALLOW Role=USER Filters=${filters} ${rule7}= Create Dictionary Operation=GETRANGEHASH Access=ALLOW Role=USER Filters=${filters} ${eACL_gen}= Create List ${rule1} ${rule2} ${rule3} ${rule4} ${rule5} ${rule6} ${rule7} - + ${EACL_TOKEN} = Form BearerToken File ${USER_KEY} ${CID} ${eACL_gen} Run Keyword And Expect Error ${EACL_ERROR_MSG} diff --git a/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_not_equal.robot b/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_not_equal.robot index 668a4d10..39ae327c 100644 --- a/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_not_equal.robot +++ b/robot/testsuites/integration/acl/acl_bearer_request_filter_xheader_not_equal.robot @@ -4,6 +4,7 @@ Variables common.py Library Collections Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource eacl_tables.robot @@ -46,7 +47,7 @@ Check eACL Deny and Allow All Bearer Filter Requst NotEqual ${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_HEADER} ${S_OID_USER_2} = Put object ${USER_KEY} ${FILE_S} ${CID} ${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${USER_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} user_headers=${ANOTHER_USER_HEADER} Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl diff --git a/robot/testsuites/integration/acl/acl_extended_actions_other.robot b/robot/testsuites/integration/acl/acl_extended_actions_other.robot index b3355b00..7a50ee39 100644 --- a/robot/testsuites/integration/acl/acl_extended_actions_other.robot +++ b/robot/testsuites/integration/acl/acl_extended_actions_other.robot @@ -1,10 +1,8 @@ *** Settings *** Variables common.py -Library Collections Library neofs.py Library payment_neogo.py -Library acl.py Resource common_steps_acl_extended.robot Resource payment_operations.robot @@ -19,7 +17,7 @@ Extended ACL Operations [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit + ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit Log Check extended ACL with simple object @@ -37,4 +35,4 @@ Extended ACL Operations Check eACL Deny and Allow All Other [Arguments] ${USER_KEY} ${OTHER_KEY} - Check eACL Deny and Allow All ${OTHER_KEY} ${EACL_DENY_ALL_OTHERS} ${EACL_ALLOW_ALL_OTHERS} ${USER_KEY} + Check eACL Deny and Allow All ${OTHER_KEY} ${EACL_DENY_ALL_OTHERS} ${EACL_ALLOW_ALL_OTHERS} ${USER_KEY} diff --git a/robot/testsuites/integration/acl/acl_extended_actions_pubkey.robot b/robot/testsuites/integration/acl/acl_extended_actions_pubkey.robot index 31881f3c..fbb55ee7 100644 --- a/robot/testsuites/integration/acl/acl_extended_actions_pubkey.robot +++ b/robot/testsuites/integration/acl/acl_extended_actions_pubkey.robot @@ -4,6 +4,7 @@ Variables common.py Library Collections Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource common_steps_acl_extended.robot diff --git a/robot/testsuites/integration/acl/acl_extended_actions_system.robot b/robot/testsuites/integration/acl/acl_extended_actions_system.robot index c1928003..f9901f22 100644 --- a/robot/testsuites/integration/acl/acl_extended_actions_system.robot +++ b/robot/testsuites/integration/acl/acl_extended_actions_system.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library acl.py @@ -19,7 +20,7 @@ Resource eacl_tables.robot *** Test cases *** Extended ACL Operations [Documentation] Testcase to validate NeoFS operations with extended ACL. - [Tags] ACL eACL NeoFS NeoCLI + [Tags] ACL eACL [Timeout] 20 min [Setup] Setup diff --git a/robot/testsuites/integration/acl/acl_extended_actions_user.robot b/robot/testsuites/integration/acl/acl_extended_actions_user.robot index 84665bc9..abee4908 100644 --- a/robot/testsuites/integration/acl/acl_extended_actions_user.robot +++ b/robot/testsuites/integration/acl/acl_extended_actions_user.robot @@ -14,7 +14,7 @@ Resource eacl_tables.robot *** Test cases *** Extended ACL Operations [Documentation] Testcase to validate NeoFS operations with extended ACL. - [Tags] ACL eACL NeoFS NeoCLI + [Tags] ACL eACL [Timeout] 20 min [Setup] Setup diff --git a/robot/testsuites/integration/acl/acl_extended_compound.robot b/robot/testsuites/integration/acl/acl_extended_compound.robot index 669c34f8..b5bf8629 100644 --- a/robot/testsuites/integration/acl/acl_extended_compound.robot +++ b/robot/testsuites/integration/acl/acl_extended_compound.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library acl.py diff --git a/robot/testsuites/integration/acl/acl_extended_deny_replication.robot b/robot/testsuites/integration/acl/acl_extended_deny_replication.robot index e7301c57..0eaa83d2 100644 --- a/robot/testsuites/integration/acl/acl_extended_deny_replication.robot +++ b/robot/testsuites/integration/acl/acl_extended_deny_replication.robot @@ -3,6 +3,7 @@ Variables common.py Library Collections Library neofs.py +Library neofs_verbs.py Library acl.py Library payment_neogo.py diff --git a/robot/testsuites/integration/acl/acl_extended_filters.robot b/robot/testsuites/integration/acl/acl_extended_filters.robot index 13d71851..d9707a65 100644 --- a/robot/testsuites/integration/acl/acl_extended_filters.robot +++ b/robot/testsuites/integration/acl/acl_extended_filters.robot @@ -3,6 +3,7 @@ Variables common.py Library acl.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library Collections Library contract_keywords.py @@ -16,8 +17,8 @@ Resource eacl_tables.robot ${PATH} = testfile &{USER_HEADER} = key1=1 key2=abc &{ANOTHER_HEADER} = key1=oth key2=oth -${ID_FILTER} = $Object:objectID -${CUSTOM_FILTER} = $Object:key1 +${ID_FILTER} = $Object:objectID +${CUSTOM_FILTER} = $Object:key1 *** Test cases *** Extended ACL Operations @@ -96,7 +97,7 @@ Check eACL MatchType String Equal Request Allow ${CID} = Create Container Public ${USER_KEY} ${S_OID_USER} = Put Object ${USER_KEY} ${FILE_S} ${CID} Get Object ${OTHER_KEY} ${CID} ${S_OID_USER} ${EMPTY} ${PATH} - + Set eACL ${USER_KEY} ${CID} ${EACL_XHEADER_ALLOW_ALL} # The current ACL cache lifetime is 30 sec @@ -141,7 +142,7 @@ Check eACL MatchType String Equal Object &{HEADER_DICT} = Head Object ${USER_KEY} ${CID} ${S_OID_USER} ${ID_value} = Get From dictionary ${HEADER_DICT} ${EACL_OBJ_FILTERS}[${ID_FILTER}] - + ${filters} = Set Variable obj:${ID_FILTER}=${ID_value} ${rule1} = Set Variable deny get ${filters} others ${eACL_gen} = Create List ${rule1} @@ -154,7 +155,7 @@ Check eACL MatchType String Equal Object Log Set eACL for Deny GET operation with StringEqual Object Extended User Header ${S_OID_USER_OTH} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${ANOTHER_HEADER} - + ${filters} = Set Variable obj:${CUSTOM_FILTER}=1 ${rule1} = Set Variable deny get ${filters} others ${eACL_gen} = Create List ${rule1} @@ -178,10 +179,10 @@ Check eACL MatchType String Not Equal Object Get object ${OTHER_KEY} ${CID} ${S_OID_OTHER} ${EMPTY} ${PATH} Log Set eACL for Deny GET operation with StringNotEqual Object ID - + &{HEADER_DICT} = Head object ${USER_KEY} ${CID} ${S_OID_USER} ${ID_value} = Get From Dictionary ${HEADER_DICT} ${EACL_OBJ_FILTERS}[${ID_FILTER}] - + ${filters} = Set Variable obj:${ID_FILTER}!=${ID_value} ${rule1} = Set Variable deny get ${filters} others ${eACL_gen} = Create List ${rule1} @@ -194,8 +195,8 @@ Check eACL MatchType String Not Equal Object Log Set eACL for Deny GET operation with StringEqual Object Extended User Header - - ${S_OID_USER_OTH} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${ANOTHER_HEADER} + + ${S_OID_USER_OTH} = Put object ${USER_KEY} ${FILE_S} ${CID} user_headers=${ANOTHER_HEADER} ${filters} = Set Variable obj:${CUSTOM_FILTER}!=1 ${rule1} = Set Variable deny get ${filters} others ${eACL_gen} = Create List ${rule1} diff --git a/robot/testsuites/integration/acl/object_attributes/container_id_filter.robot b/robot/testsuites/integration/acl/object_attributes/container_id_filter.robot index a7522c89..07fee17d 100644 --- a/robot/testsuites/integration/acl/object_attributes/container_id_filter.robot +++ b/robot/testsuites/integration/acl/object_attributes/container_id_filter.robot @@ -5,11 +5,11 @@ Resource setup_teardown.robot *** Test cases *** Container ID Object Filter for Extended ACL [Documentation] Testcase to validate if $Object:containerID eACL filter is correctly handled. - [Tags] ACL eACL NeoFS NeoCLI + [Tags] ACL eACL [Timeout] 20 min [Setup] Setup - + Log Check eACL containerID Filter with MatchType String Equal Check eACL Filters with MatchType String Equal $Object:containerID diff --git a/robot/testsuites/integration/container/container_attributes.robot b/robot/testsuites/integration/container/container_attributes.robot index 62ed4f2b..7cfb7f21 100644 --- a/robot/testsuites/integration/container/container_attributes.robot +++ b/robot/testsuites/integration/container/container_attributes.robot @@ -1,10 +1,10 @@ *** Settings *** Variables common.py -Library Collections Library neofs.py Library payment_neogo.py Library String +Library Collections Resource setup_teardown.robot Resource payment_operations.robot @@ -26,7 +26,7 @@ Duplicated Container Attributes [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Init Wallet with Address ${ASSETS_DIR} + ${_} ${ADDR} ${USER_KEY} = Init Wallet with Address ${ASSETS_DIR} Payment Operations ${ADDR} ${USER_KEY} ###################################################### @@ -53,7 +53,10 @@ Duplicated Container Attributes Wait Until Keyword Succeeds ${MORPH_BLOCK_TIME} ${CONTAINER_WAIT_INTERVAL} ... Container Existing ${USER_KEY} ${CID} ${ATTRIBUTES} = Get container attributes ${USER_KEY} ${CID} ${EMPTY} json_output=True - ${ATTRIBUTES_DICT} = Decode Container Attributes Json ${ATTRIBUTES} - Verify Head Attribute ${ATTRIBUTES_DICT} ${ATTR_SINGLE} + &{ATTRIBUTES_DICT} = Decode Container Attributes Json ${ATTRIBUTES} + List Should Contain Value + ... ${ATTRIBUTES_DICT}[Attributes] + ... ${ATTR_SINGLE} + ... "No expected container attributes found" [Teardown] Teardown container_attributes diff --git a/robot/testsuites/integration/container/container_delete.robot b/robot/testsuites/integration/container/container_delete.robot index a1c71b28..744adabd 100644 --- a/robot/testsuites/integration/container/container_delete.robot +++ b/robot/testsuites/integration/container/container_delete.robot @@ -16,13 +16,13 @@ ${CONTAINER_WAIT_INTERVAL} = 1 min *** Test Cases *** Delete Containers [Documentation] Testcase to check if containers can be deleted. - [Tags] Container NeoFS NeoCLI + [Tags] Container [Timeout] 10 min [Setup] Setup - ${WALLET} ${ADDR} ${USER_KEY} = Prepare Wallet And Deposit - ${WALLET_OTH} ${ADDR_OTH} ${OTHER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${USER_KEY} = Prepare Wallet And Deposit + ${_} ${_} ${OTHER_KEY} = Prepare Wallet And Deposit ${CID} = Create container ${USER_KEY} ${PRIVATE_ACL_F} ${COMMON_PLACEMENT_RULE} Wait Until Keyword Succeeds ${MORPH_BLOCK_TIME} ${CONTAINER_WAIT_INTERVAL} @@ -41,6 +41,6 @@ Delete Containers ... Get container attributes ${USER_KEY} ${CID} Log If one tries to delete an already deleted container, they should expect success. - Delete Container ${CID} ${USER_KEY} + Delete Container ${CID} ${USER_KEY} [Teardown] Teardown container_delete diff --git a/robot/testsuites/integration/network/netmap_control_drop.robot b/robot/testsuites/integration/network/netmap_control_drop.robot index 8764c2cd..4603ea7a 100644 --- a/robot/testsuites/integration/network/netmap_control_drop.robot +++ b/robot/testsuites/integration/network/netmap_control_drop.robot @@ -2,12 +2,13 @@ Variables common.py Variables wellknown_acl.py -Library Process Library contract_keywords.py Library neofs.py -Library String +Library neofs_verbs.py Library payment_neogo.py +Library String +Library Process Resource setup_teardown.robot Resource payment_operations.robot diff --git a/robot/testsuites/integration/network/netmap_simple.robot b/robot/testsuites/integration/network/netmap_simple.robot index 2dab40c7..b235ab84 100644 --- a/robot/testsuites/integration/network/netmap_simple.robot +++ b/robot/testsuites/integration/network/netmap_simple.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library wallet_keywords.py Library rpc_call_keywords.py @@ -92,6 +93,6 @@ Validate Policy ${CID} = Create container ${PRIV_KEY} ${EMPTY} ${POLICY} Wait Until Keyword Succeeds ${MORPH_BLOCK_TIME} ${CONTAINER_WAIT_INTERVAL} ... Container Existing ${PRIV_KEY} ${CID} - ${S_OID} = Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} ${EMPTY} + ${S_OID} = Put object ${PRIV_KEY} ${FILE} ${CID} Validate storage policy for object ${PRIV_KEY} ${EXPECTED_VAL} ${CID} ${S_OID} ${EXPECTED_LIST} Get object ${PRIV_KEY} ${CID} ${S_OID} ${EMPTY} s_file_read diff --git a/robot/testsuites/integration/network/replication.robot b/robot/testsuites/integration/network/replication.robot index e8716e80..f4c64016 100644 --- a/robot/testsuites/integration/network/replication.robot +++ b/robot/testsuites/integration/network/replication.robot @@ -5,6 +5,7 @@ Variables wellknown_acl.py Library Collections Library payment_neogo.py Library neofs.py +Library neofs_verbs.py Library wallet_keywords.py Library rpc_call_keywords.py Library contract_keywords.py @@ -25,10 +26,10 @@ NeoFS Object Replication [Timeout] 25 min [Setup] Setup - + Log Check replication mechanism Check Replication ${EMPTY} - 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} [Teardown] Teardown replication @@ -37,7 +38,7 @@ NeoFS Object Replication Check Replication [Arguments] ${ACL} - ${WALLET} ${ADDR} ${WIF} = Prepare Wallet And Deposit + ${_} ${_} ${WIF} = Prepare Wallet And Deposit ${CID} = Create Container ${WIF} ${ACL} ${PLACEMENT_RULE} Wait Until Keyword Succeeds ${MORPH_BLOCK_TIME} ${CONTAINER_WAIT_INTERVAL} ... Container Existing ${WIF} ${CID} @@ -45,7 +46,7 @@ Check Replication ${FILE} = Generate file of bytes ${SIMPLE_OBJ_SIZE} ${FILE_HASH} = Get file hash ${FILE} - ${S_OID} = Put Object ${WIF} ${FILE} ${CID} ${EMPTY} ${EMPTY} + ${S_OID} = Put Object ${WIF} ${FILE} ${CID} Validate storage policy for object ${WIF} ${EXPECTED_COPIES} ${CID} ${S_OID} @{NODES_OBJ} = Get nodes with Object ${WIF} ${CID} ${S_OID} diff --git a/robot/testsuites/integration/object/object_attributes.robot b/robot/testsuites/integration/object/object_attributes.robot index aab961bd..4796840e 100644 --- a/robot/testsuites/integration/object/object_attributes.robot +++ b/robot/testsuites/integration/object/object_attributes.robot @@ -2,10 +2,11 @@ Variables common.py Variables wellknown_acl.py -Library Collections Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library String +Library Collections Resource setup_teardown.robot Resource payment_operations.robot diff --git a/robot/testsuites/integration/object/object_complex.robot b/robot/testsuites/integration/object/object_complex.robot index 7d921900..3b1c8a09 100644 --- a/robot/testsuites/integration/object/object_complex.robot +++ b/robot/testsuites/integration/object/object_complex.robot @@ -1,6 +1,7 @@ *** Settings *** Variables common.py +Library neofs_verbs.py Library neofs.py Library payment_neogo.py Library contract_keywords.py diff --git a/robot/testsuites/integration/object/object_expiration.robot b/robot/testsuites/integration/object/object_expiration.robot index 1794cd7e..e82c2577 100644 --- a/robot/testsuites/integration/object/object_expiration.robot +++ b/robot/testsuites/integration/object/object_expiration.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library contract_keywords.py @@ -35,12 +36,12 @@ NeoFS Simple Object Operations # Failed on attempt to create epoch from the past Run Keyword And Expect Error * - ... Put object ${WIF} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH_PRE} + ... Put object ${WIF} ${FILE} ${CID} options= --attributes __NEOFS__EXPIRATION_EPOCH=${EPOCH_PRE} # Put object with different expiration epoch numbers (current, next, and from the distant future) - ${OID_CUR} = Put object ${WIF} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH} - ${OID_NXT} = Put object ${WIF} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH_NEXT} - ${OID_PST} = Put object ${WIF} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH_POST} + ${OID_CUR} = Put object ${WIF} ${FILE} ${CID} options= --attributes __NEOFS__EXPIRATION_EPOCH=${EPOCH} + ${OID_NXT} = Put object ${WIF} ${FILE} ${CID} options= --attributes __NEOFS__EXPIRATION_EPOCH=${EPOCH_NEXT} + ${OID_PST} = Put object ${WIF} ${FILE} ${CID} options= --attributes __NEOFS__EXPIRATION_EPOCH=${EPOCH_POST} # Check objects for existence Get object ${WIF} ${CID} ${OID_CUR} ${EMPTY} file_read_cur diff --git a/robot/testsuites/integration/object/object_simple.robot b/robot/testsuites/integration/object/object_simple.robot index 08ce5dc1..fb3cfcbe 100644 --- a/robot/testsuites/integration/object/object_simple.robot +++ b/robot/testsuites/integration/object/object_simple.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Library contract_keywords.py Library Collections @@ -25,7 +26,7 @@ NeoFS Simple Object Operations [Setup] Setup ${WALLET} ${ADDR} ${WIF} = Init Wallet with Address ${ASSETS_DIR} - Payment Operations ${ADDR} ${WIF} + Payment Operations ${ADDR} ${WIF} ${CID} = Prepare container ${WIF} ${FILE} = Generate file of bytes ${SIMPLE_OBJ_SIZE} diff --git a/robot/testsuites/integration/object/object_storagegroup_complex.robot b/robot/testsuites/integration/object/object_storagegroup_complex.robot index 295c6b01..5fc13efd 100644 --- a/robot/testsuites/integration/object/object_storagegroup_complex.robot +++ b/robot/testsuites/integration/object/object_storagegroup_complex.robot @@ -1,9 +1,10 @@ *** Settings *** Variables common.py -Library Collections Library neofs.py +Library neofs_verbs.py Library payment_neogo.py +Library Collections Resource common_steps_object.robot Resource setup_teardown.robot @@ -11,11 +12,12 @@ Resource payment_operations.robot *** Variables *** ${UNEXIST_OID} = B2DKvkHnLnPvapbDgfpU1oVUPuXQo5LTfKVxmNDZXQff +&{USER_HEADER} = key1=1 key2=2 *** Test cases *** NeoFS Complex Storagegroup [Documentation] Testcase to validate NeoFS operations with Storagegroup. - [Tags] Object NeoFS NeoCLI + [Tags] Object [Timeout] 20 min [Setup] Setup @@ -28,8 +30,8 @@ NeoFS Complex Storagegroup ${FILE_HASH_S} = Get file hash ${FILE_S} # Put two Simple Object - ${S_OID_1} = Put object ${WIF} ${FILE_S} ${CID} ${EMPTY} ${EMPTY} - ${S_OID_2} = Put object ${WIF} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER} + ${S_OID_1} = Put object ${WIF} ${FILE_S} ${CID} + ${S_OID_2} = Put object ${WIF} ${FILE_S} ${CID} user_headers=&{USER_HEADER} @{S_OBJ_ALL} = Create List ${S_OID_1} ${S_OID_2} diff --git a/robot/testsuites/integration/object/object_storagegroup_simple.robot b/robot/testsuites/integration/object/object_storagegroup_simple.robot index 119773a6..021795f3 100644 --- a/robot/testsuites/integration/object/object_storagegroup_simple.robot +++ b/robot/testsuites/integration/object/object_storagegroup_simple.robot @@ -2,6 +2,7 @@ Variables common.py Library neofs.py +Library neofs_verbs.py Library payment_neogo.py Resource common_steps_object.robot @@ -10,6 +11,7 @@ Resource payment_operations.robot *** Variables *** ${UNEXIST_OID} = B2DKvkHnLnPvapbDgfpU1oVUPuXQo5LTfKVxmNDZXQff +&{USER_HEADER} = key1=1 key2=2 *** Test cases *** NeoFS Simple Storagegroup @@ -28,8 +30,8 @@ NeoFS Simple Storagegroup # Put two Simple Object - ${S_OID_1} = Put object ${WIF} ${FILE_S} ${CID} ${EMPTY} ${EMPTY} - ${S_OID_2} = Put object ${WIF} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER} + ${S_OID_1} = Put object ${WIF} ${FILE_S} ${CID} + ${S_OID_2} = Put object ${WIF} ${FILE_S} ${CID} user_headers=&{USER_HEADER} @{S_OBJ_ALL} = Create List ${S_OID_1} ${S_OID_2} diff --git a/robot/testsuites/integration/services/http_gate.robot b/robot/testsuites/integration/services/http_gate.robot index c8ed46e3..4c82f39d 100644 --- a/robot/testsuites/integration/services/http_gate.robot +++ b/robot/testsuites/integration/services/http_gate.robot @@ -3,6 +3,7 @@ Variables common.py Variables wellknown_acl.py Library neofs.py +Library neofs_verbs.py Library http_gate.py Resource payment_operations.robot @@ -33,8 +34,8 @@ NeoFS HTTP Gateway ${FILE_HASH} = Get file hash ${FILE} ${FILE_L_HASH} = Get file hash ${FILE_L} - ${S_OID} = Put object ${WIF} ${FILE} ${CID} ${EMPTY} ${EMPTY} - ${L_OID} = Put object ${WIF} ${FILE_L} ${CID} ${EMPTY} ${EMPTY} + ${S_OID} = Put object ${WIF} ${FILE} ${CID} + ${L_OID} = Put object ${WIF} ${FILE_L} ${CID} # By request from Service team - try to GET object from the node without object @@ -44,8 +45,10 @@ NeoFS HTTP Gateway ${GET_OBJ_S} = Get object ${WIF} ${CID} ${S_OID} ${EMPTY} s_file_read ${NODE} ${FILEPATH} = Get via HTTP Gate ${CID} ${S_OID} - Verify file hash ${GET_OBJ_S} ${FILE_HASH} - Verify file hash ${FILEPATH} ${FILE_HASH} + ${PLAIN_FILE_HASH} = Get file hash ${GET_OBJ_S} + ${GATE_FILE_HASH} = Get file hash ${FILEPATH} + Should Be Equal ${FILE_HASH} ${PLAIN_FILE_HASH} + Should Be Equal ${FILE_HASH} ${GATE_FILE_HASH} @{GET_NODE_LIST} = Get nodes without object ${WIF} ${CID} ${L_OID} ${NODE} = Evaluate random.choice($GET_NODE_LIST) random @@ -53,7 +56,9 @@ NeoFS HTTP Gateway ${GET_OBJ_L} = Get object ${WIF} ${CID} ${L_OID} ${EMPTY} l_file_read ${NODE} ${FILEPATH} = Get via HTTP Gate ${CID} ${L_OID} - Verify file hash ${GET_OBJ_L} ${FILE_L_HASH} - Verify file hash ${FILEPATH} ${FILE_L_HASH} + ${PLAIN_FILE_HASH} = Get file hash ${GET_OBJ_L} + ${GATE_FILE_HASH} = Get file hash ${FILEPATH} + Should Be Equal ${FILE_L_HASH} ${PLAIN_FILE_HASH} + Should Be Equal ${FILE_L_HASH} ${GATE_FILE_HASH} [Teardown] Teardown http_gate diff --git a/robot/testsuites/integration/services/s3_gate_object.robot b/robot/testsuites/integration/services/s3_gate_object.robot index 79ead27b..e79408a0 100644 --- a/robot/testsuites/integration/services/s3_gate_object.robot +++ b/robot/testsuites/integration/services/s3_gate_object.robot @@ -58,6 +58,8 @@ Objects in NeoFS S3 Gateway ${OBJ_PATH} = Get object S3 ${S3_CLIENT} ${NEW_BUCKET} ${S3_OBJECT_KEY} Verify file hash ${OBJ_PATH} ${FILE_S3_HASH} + ${HASH} = Get file hash ${OBJ_PATH} + Should Be Equal ${FILE_S3_HASH} ${HASH} #TODO: Solve the issue on CopyObject #260 https://github.com/nspcc-dev/neofs-s3-gw/issues/260