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