Feature/storagegroup acl (#33)
* update contracts to the latest NeoFS version * update neo-go command execution to the NeoGo v0.93.0 * Add Storagegroup basic ACL check to the basic ACL test cases * update expected values of GAS in the withdraw testcase * update netmap test case to work with LOCODE
This commit is contained in:
parent
e2983c8539
commit
1cd77ddd55
12 changed files with 172 additions and 57 deletions
|
@ -69,6 +69,7 @@ The following UserScenarios and testcases are available for execution:
|
||||||
* object_complex.robot
|
* object_complex.robot
|
||||||
* object_simple.robot
|
* object_simple.robot
|
||||||
* object_storagegroup_simple.robot
|
* object_storagegroup_simple.robot
|
||||||
|
* object_storagegroup_complex.robot
|
||||||
* payment
|
* payment
|
||||||
* withdraw.robot
|
* withdraw.robot
|
||||||
* services
|
* services
|
||||||
|
|
|
@ -374,14 +374,18 @@ def generate_file_of_bytes(size):
|
||||||
def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: str,
|
def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: str,
|
||||||
expected_objects_list=[], options:str=""):
|
expected_objects_list=[], options:str=""):
|
||||||
bearer_token = ""
|
bearer_token = ""
|
||||||
|
filters_result = ""
|
||||||
|
|
||||||
if bearer:
|
if bearer:
|
||||||
bearer_token = f"--bearer {bearer}"
|
bearer_token = f"--bearer {bearer}"
|
||||||
if filters:
|
if filters:
|
||||||
filters = f"--filters {filters}"
|
for filter_item in filters.split(','):
|
||||||
|
filter_item = re.sub(r'=', ' EQ ', filter_item)
|
||||||
|
filters_result += f"--filters '{filter_item}' "
|
||||||
|
|
||||||
ObjectCmd = (
|
ObjectCmd = (
|
||||||
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} '
|
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} '
|
||||||
f'object search {keys} --cid {cid} {bearer_token} {filters} {options}'
|
f'object search {keys} --cid {cid} {bearer_token} {filters_result} {options}'
|
||||||
)
|
)
|
||||||
logger.info("Cmd: %s" % ObjectCmd)
|
logger.info("Cmd: %s" % ObjectCmd)
|
||||||
try:
|
try:
|
||||||
|
@ -402,6 +406,7 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
|
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
|
||||||
|
|
||||||
|
|
||||||
@keyword('Get Split objects')
|
@keyword('Get Split objects')
|
||||||
def get_component_objects(private_key: str, cid: str, oid: str):
|
def get_component_objects(private_key: str, cid: str, oid: str):
|
||||||
|
@ -952,13 +957,13 @@ def get_object(private_key: str, cid: str, oid: str, bearer_token: str,
|
||||||
|
|
||||||
|
|
||||||
@keyword('Put Storagegroup')
|
@keyword('Put Storagegroup')
|
||||||
def put_storagegroup(private_key: str, cid: str, *oid_list):
|
def put_storagegroup(private_key: str, cid: str, options: str="", *oid_list):
|
||||||
|
|
||||||
cmd_oid_line = ",".join(oid_list)
|
cmd_oid_line = ",".join(oid_list)
|
||||||
|
|
||||||
ObjectCmd = (
|
ObjectCmd = (
|
||||||
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} storagegroup '
|
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} storagegroup '
|
||||||
f'put --cid {cid} --members {cmd_oid_line}'
|
f'put --cid {cid} --members {cmd_oid_line} {options}'
|
||||||
)
|
)
|
||||||
logger.info(f"Cmd: {ObjectCmd}")
|
logger.info(f"Cmd: {ObjectCmd}")
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -9,5 +9,5 @@ HTTP_GATE = 'http://http.neofs.devenv'
|
||||||
S3_GATE = 'https://s3.neofs.devenv:8080'
|
S3_GATE = 'https://s3.neofs.devenv:8080'
|
||||||
NEOFS_NETMAP = ['s01.neofs.devenv:8080', 's02.neofs.devenv:8080','s03.neofs.devenv:8080','s04.neofs.devenv:8080']
|
NEOFS_NETMAP = ['s01.neofs.devenv:8080', 's02.neofs.devenv:8080','s03.neofs.devenv:8080','s04.neofs.devenv:8080']
|
||||||
|
|
||||||
GAS_HASH = '0xa6a6c15dcdc9b997dac448b6926522d22efeedfb'
|
GAS_HASH = '0x70e2301955bf1e74cbb31d18c2f96972abadb328'
|
||||||
NEOFS_CONTRACT = "e11db12b0df3b3c05e6ed5f85e5cf53236e9dbeb"
|
NEOFS_CONTRACT = "005a4906ec233a3b677dad9fd7033ad8653f579d"
|
||||||
|
|
|
@ -41,29 +41,13 @@ def init_wallet():
|
||||||
@keyword('Generate wallet from WIF')
|
@keyword('Generate wallet from WIF')
|
||||||
def generate_wallet_from_wif(wallet: str, wif: str):
|
def generate_wallet_from_wif(wallet: str, wif: str):
|
||||||
cmd = f"{NEOGO_CLI_EXEC} wallet import --wallet {wallet} --wif {wif}"
|
cmd = f"{NEOGO_CLI_EXEC} wallet import --wallet {wallet} --wif {wif}"
|
||||||
logger.info(f"Executing command: {cmd}")
|
out = _run_sh_wallet_gen(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}")
|
logger.info(f"Command completed with output: {out}")
|
||||||
|
|
||||||
@keyword('Generate wallet')
|
@keyword('Generate wallet')
|
||||||
def generate_wallet(wallet: str):
|
def generate_wallet(wallet: str):
|
||||||
cmd = f"{NEOGO_CLI_EXEC} wallet create -w {wallet}"
|
cmd = f"{NEOGO_CLI_EXEC} wallet create -w {wallet}"
|
||||||
logger.info(f"Executing command: {cmd}")
|
out = _run_sh_wallet_gen(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}")
|
logger.info(f"Command completed with output: {out}")
|
||||||
|
|
||||||
@keyword('Dump Address')
|
@keyword('Dump Address')
|
||||||
|
@ -79,7 +63,7 @@ def dump_address(wallet: str):
|
||||||
def dump_privkey(wallet: str, address: str):
|
def dump_privkey(wallet: str, address: str):
|
||||||
cmd = f"{NEOGO_CLI_EXEC} wallet export -w {wallet} --decrypt {address}"
|
cmd = f"{NEOGO_CLI_EXEC} wallet export -w {wallet} --decrypt {address}"
|
||||||
logger.info(f"Executing command: {cmd}")
|
logger.info(f"Executing command: {cmd}")
|
||||||
out = _run_sh_with_passwd('', cmd)
|
out = _run_sh_with_passwd('\r', cmd)
|
||||||
logger.info(f"Command completed with output: {out}")
|
logger.info(f"Command completed with output: {out}")
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
@ -277,9 +261,26 @@ def _run_sh(args):
|
||||||
def _run_sh_with_passwd(passwd, cmd):
|
def _run_sh_with_passwd(passwd, cmd):
|
||||||
p = pexpect.spawn(cmd)
|
p = pexpect.spawn(cmd)
|
||||||
p.expect(".*")
|
p.expect(".*")
|
||||||
p.sendline(passwd)
|
p.sendline(passwd + '\r')
|
||||||
p.wait()
|
p.wait()
|
||||||
# throw a string with password prompt
|
# throw a string with password prompt
|
||||||
# take a string with tx hash
|
# take a string with tx hash
|
||||||
tx_hash = p.read().splitlines()[-1]
|
tx_hash = p.read().splitlines()[-1]
|
||||||
return tx_hash.decode()
|
return tx_hash.decode()
|
||||||
|
|
||||||
|
def _run_sh_wallet_gen(cmd):
|
||||||
|
'''
|
||||||
|
Internal method.
|
||||||
|
'''
|
||||||
|
logger.info(f"Executing command: {cmd}")
|
||||||
|
p = pexpect.spawn(cmd)
|
||||||
|
p.expect(".*")
|
||||||
|
p.sendline('\r')
|
||||||
|
p.expect(".*")
|
||||||
|
p.sendline('\r')
|
||||||
|
p.expect(".*")
|
||||||
|
p.sendline('\r')
|
||||||
|
p.wait()
|
||||||
|
out = p.read()
|
||||||
|
|
||||||
|
return out
|
|
@ -1,6 +1,6 @@
|
||||||
*** Settings ***
|
*** Settings ***
|
||||||
Variables ../../../variables/common.py
|
Variables ../../../variables/common.py
|
||||||
|
Library Collections
|
||||||
Library ../${RESOURCES}/neofs.py
|
Library ../${RESOURCES}/neofs.py
|
||||||
Library ../${RESOURCES}/payment_neogo.py
|
Library ../${RESOURCES}/payment_neogo.py
|
||||||
|
|
||||||
|
@ -17,11 +17,11 @@ Basic ACL Operations for Private Container
|
||||||
|
|
||||||
Create Containers
|
Create Containers
|
||||||
Generate file 1024
|
Generate file 1024
|
||||||
Check Private Container
|
Check Private Container Simple
|
||||||
|
|
||||||
Create Containers
|
Create Containers
|
||||||
Generate file 70e+6
|
Generate file 70e+6
|
||||||
Check Private Container
|
Check Private Container Complex
|
||||||
|
|
||||||
[Teardown] Cleanup
|
[Teardown] Cleanup
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@ Basic ACL Operations for Private Container
|
||||||
*** Keywords ***
|
*** Keywords ***
|
||||||
|
|
||||||
Check Private Container
|
Check Private Container
|
||||||
|
[Arguments] ${RUN_TYPE}
|
||||||
|
|
||||||
|
# Put
|
||||||
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Put object ${OTHER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
... Put object ${OTHER_KEY} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||||
|
@ -38,7 +41,46 @@ Check Private Container
|
||||||
... Put object ${SYSTEM_KEY_IR} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
... Put object ${SYSTEM_KEY_IR} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||||
${S_OID_SYS_SN} = Put object ${SYSTEM_KEY_SN} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
${S_OID_SYS_SN} = Put object ${SYSTEM_KEY_SN} ${FILE_S} ${PRIV_CID} ${EMPTY} ${EMPTY}
|
||||||
|
|
||||||
|
# Storage group Operations (Put, List, Get, Delete)
|
||||||
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
List Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID_1} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID_1} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Delete Storagegroup ${USER_KEY} ${PRIV_CID} ${SG_OID_1}
|
||||||
|
|
||||||
|
|
||||||
|
${SG_OID_1} = Put Storagegroup ${SYSTEM_KEY_SN} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
List Storagegroup ${SYSTEM_KEY_SN} ${PRIV_CID} ${SG_OID_1} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${SYSTEM_KEY_SN} ${PRIV_CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${SYSTEM_KEY_SN} ${PRIV_CID} ${SG_OID_1} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Delete Storagegroup ${SYSTEM_KEY_SN} ${PRIV_CID} ${SG_OID_1}
|
||||||
|
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Put Storagegroup ${OTHER_KEY} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... List Storagegroup ${OTHER_KEY} ${PRIV_CID} ${SG_OID_INV}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Get Storagegroup ${OTHER_KEY} ${PRIV_CID} ${SG_OID_INV} ${EMPTY} ${S_OID_USER}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Delete Storagegroup ${OTHER_KEY} ${PRIV_CID} ${SG_OID_INV}
|
||||||
|
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Put Storagegroup ${SYSTEM_KEY_IR} ${PRIV_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... List Storagegroup ${SYSTEM_KEY_IR} ${PRIV_CID} ${SG_OID_INV}
|
||||||
|
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${PRIV_CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${SYSTEM_KEY_IR} ${PRIV_CID} ${SG_OID_INV} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Delete Storagegroup ${SYSTEM_KEY_IR} ${PRIV_CID} ${SG_OID_INV}
|
||||||
|
|
||||||
|
|
||||||
# Get
|
# Get
|
||||||
Get object ${USER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
Get object ${USER_KEY} ${PRIV_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
|
|
@ -17,11 +17,11 @@ Basic ACL Operations for Public Container
|
||||||
|
|
||||||
Create Containers
|
Create Containers
|
||||||
Generate file 1024
|
Generate file 1024
|
||||||
Check Public Container
|
Check Public Container Simple
|
||||||
|
|
||||||
Create Containers
|
Create Containers
|
||||||
Generate file 70e+6
|
Generate file 70e+6
|
||||||
Check Public Container
|
Check Public Container Complex
|
||||||
|
|
||||||
[Teardown] Cleanup
|
[Teardown] Cleanup
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ Basic ACL Operations for Public Container
|
||||||
*** Keywords ***
|
*** Keywords ***
|
||||||
|
|
||||||
Check Public Container
|
Check Public Container
|
||||||
|
[Arguments] ${RUN_TYPE}
|
||||||
|
|
||||||
# Put
|
# Put
|
||||||
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
||||||
|
@ -86,6 +87,21 @@ Check Public Container
|
||||||
Delete object ${SYSTEM_KEY_SN} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY}
|
Delete object ${SYSTEM_KEY_SN} ${PUBLIC_CID} ${S_OID_OTHER} ${EMPTY}
|
||||||
|
|
||||||
|
|
||||||
|
# Storage group Operations (Put, List, Get, Delete)
|
||||||
|
Log Storage group Operations for each Role keys
|
||||||
|
${S_OID} = Put object ${USER_KEY} ${FILE_S} ${PUBLIC_CID} ${EMPTY} ${EMPTY}
|
||||||
|
@{Roles_keys} = Create List ${USER_KEY} ${OTHER_KEY} ${SYSTEM_KEY_IR} ${SYSTEM_KEY_SN}
|
||||||
|
FOR ${role_key} IN @{Roles_keys}
|
||||||
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${PUBLIC_CID} ${EMPTY} ${S_OID}
|
||||||
|
List Storagegroup ${USER_KEY} ${PUBLIC_CID} ${SG_OID_1}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${PUBLIC_CID} ${S_OID}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID}
|
||||||
|
Get Storagegroup ${USER_KEY} ${PUBLIC_CID} ${SG_OID_1} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Delete Storagegroup ${USER_KEY} ${PUBLIC_CID} ${SG_OID_1}
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
Cleanup
|
Cleanup
|
||||||
@{CLEANUP_FILES} = Create List ${FILE_S} s_file_read s_get_range
|
@{CLEANUP_FILES} = Create List ${FILE_S} s_file_read s_get_range
|
||||||
Cleanup Files @{CLEANUP_FILES}
|
Cleanup Files @{CLEANUP_FILES}
|
||||||
|
|
|
@ -17,11 +17,11 @@ Basic ACL Operations for Read-Only Container
|
||||||
|
|
||||||
Create Containers
|
Create Containers
|
||||||
Generate file 1024
|
Generate file 1024
|
||||||
Check Read-Only Container
|
Check Read-Only Container Simple
|
||||||
|
|
||||||
Create Containers
|
Create Containers
|
||||||
Generate file 70e+6
|
Generate file 70e+6
|
||||||
Check Read-Only Container
|
Check Read-Only Container Complex
|
||||||
|
|
||||||
[Teardown] Cleanup
|
[Teardown] Cleanup
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ Basic ACL Operations for Read-Only Container
|
||||||
|
|
||||||
|
|
||||||
Check Read-Only Container
|
Check Read-Only Container
|
||||||
# Check Read Only container:
|
[Arguments] ${RUN_TYPE}
|
||||||
|
|
||||||
# Put
|
# 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} ${EMPTY} ${EMPTY}
|
||||||
|
@ -40,6 +40,34 @@ Check Read-Only Container
|
||||||
... Put object ${SYSTEM_KEY_IR} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
... Put object ${SYSTEM_KEY_IR} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
||||||
${S_OID_SYS_SN} = Put object ${SYSTEM_KEY_SN} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
${S_OID_SYS_SN} = Put object ${SYSTEM_KEY_SN} ${FILE_S} ${READONLY_CID} ${EMPTY} ${EMPTY}
|
||||||
|
|
||||||
|
|
||||||
|
# Storage group Operations (Put, List, Get, Delete)
|
||||||
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
List Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Delete Storagegroup ${USER_KEY} ${READONLY_CID} ${SG_OID_1}
|
||||||
|
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Put Storagegroup ${OTHER_KEY} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
List Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Delete Storagegroup ${OTHER_KEY} ${READONLY_CID} ${SG_OID_INV}
|
||||||
|
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Put Storagegroup ${SYSTEM_KEY_IR} ${READONLY_CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
List Storagegroup ${SYSTEM_KEY_IR} ${READONLY_CID} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${READONLY_CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${SYSTEM_KEY_IR} ${READONLY_CID} ${SG_OID_INV} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Delete Storagegroup ${SYSTEM_KEY_IR} ${READONLY_CID} ${SG_OID_INV}
|
||||||
|
|
||||||
# Get
|
# Get
|
||||||
Get object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
Get object ${USER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||||
Get object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
Get object ${OTHER_KEY} ${READONLY_CID} ${S_OID_USER} ${EMPTY} s_file_read
|
||||||
|
|
|
@ -18,12 +18,13 @@ BearerToken Operations
|
||||||
|
|
||||||
Log Check Bearer token with simple object
|
Log Check Bearer token with simple object
|
||||||
Generate file 1024
|
Generate file 1024
|
||||||
Check eACL Deny and Allow All Bearer
|
Check eACL Deny and Allow All Bearer Simple
|
||||||
|
|
||||||
Log Check Bearer token with complex object
|
Log Check Bearer token with complex object
|
||||||
Cleanup Files ${FILE_S}
|
Cleanup Files ${FILE_S}
|
||||||
Generate file 70e+6
|
Generate file 70e+6
|
||||||
Check eACL Deny and Allow All Bearer
|
Check eACL Deny and Allow All Bearer Complex
|
||||||
|
|
||||||
|
|
||||||
[Teardown] Cleanup
|
[Teardown] Cleanup
|
||||||
|
|
||||||
|
@ -32,21 +33,30 @@ BearerToken Operations
|
||||||
*** Keywords ***
|
*** Keywords ***
|
||||||
|
|
||||||
Check eACL Deny and Allow All Bearer
|
Check eACL Deny and Allow All Bearer
|
||||||
|
[Arguments] ${RUN_TYPE}
|
||||||
${CID} = Create Container Public
|
${CID} = Create Container Public
|
||||||
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
${S_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
||||||
${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER_DEL}
|
${D_OID_USER} = Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER_DEL}
|
||||||
@{S_OBJ_H} = Create List ${S_OID_USER}
|
@{S_OBJ_H} = Create List ${S_OID_USER}
|
||||||
|
|
||||||
|
|
||||||
Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_OTH_HEADER}
|
Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_OTH_HEADER}
|
||||||
Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
||||||
Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||||
Head object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
Head object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
||||||
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range ${EMPTY} 0:256
|
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range ${EMPTY} 0:256
|
||||||
Delete object ${USER_KEY} ${CID} ${D_OID_USER} ${EMPTY}
|
Delete object ${USER_KEY} ${CID} ${D_OID_USER} ${EMPTY}
|
||||||
|
|
||||||
Set eACL ${USER_KEY} ${CID} ${EACL_DENY_ALL_USER} --await
|
# Storage group Operations (Put, List, Get, Delete)
|
||||||
|
${SG_OID_INV} = Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
${SG_OID_1} = Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
List Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Get Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Delete Storagegroup ${USER_KEY} ${CID} ${SG_OID_1}
|
||||||
|
|
||||||
|
Set eACL ${USER_KEY} ${CID} ${EACL_DENY_ALL_USER} --await
|
||||||
|
|
||||||
${rule1}= Create Dictionary Operation=GET Access=ALLOW Role=USER
|
${rule1}= Create Dictionary Operation=GET Access=ALLOW Role=USER
|
||||||
${rule2}= Create Dictionary Operation=HEAD Access=ALLOW Role=USER
|
${rule2}= Create Dictionary Operation=HEAD Access=ALLOW Role=USER
|
||||||
|
@ -61,9 +71,9 @@ Check eACL Deny and Allow All Bearer
|
||||||
Form BearerToken file ${USER_KEY} ${CID} bearer_allow_all_user ${eACL_gen} 100500
|
Form BearerToken file ${USER_KEY} ${CID} bearer_allow_all_user ${eACL_gen} 100500
|
||||||
|
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
... Put object ${USER_KEY} ${FILE_S} ${CID} ${EMPTY} ${FILE_USR_HEADER}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
... Get object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY} local_file_eacl
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
... Search object ${USER_KEY} ${CID} ${EMPTY} ${EMPTY} ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
|
@ -73,8 +83,20 @@ Check eACL Deny and Allow All Bearer
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Delete object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
... Delete object ${USER_KEY} ${CID} ${S_OID_USER} ${EMPTY}
|
||||||
|
|
||||||
Put object ${USER_KEY} ${FILE_S} ${CID} bearer_allow_all_user ${FILE_OTH_HEADER}
|
Run Keyword And Expect Error *
|
||||||
Get object ${USER_KEY} ${CID} ${S_OID_USER} bearer_allow_all_user local_file_eacl
|
... Put Storagegroup ${USER_KEY} ${CID} ${EMPTY} ${S_OID_USER}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... List Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${SG_OID_INV}
|
||||||
|
@{EXPECTED_OIDS} = Run Keyword If "${RUN_TYPE}" == "Complex" Get Split objects ${USER_KEY} ${CID} ${S_OID_USER}
|
||||||
|
... ELSE IF "${RUN_TYPE}" == "Simple" Create List ${S_OID_USER}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Get Storagegroup ${USER_KEY} ${CID} ${SG_OID_1} ${EMPTY} @{EXPECTED_OIDS}
|
||||||
|
Run Keyword And Expect Error *
|
||||||
|
... Delete Storagegroup ${USER_KEY} ${CID} ${SG_OID_1}
|
||||||
|
|
||||||
|
|
||||||
|
Put object ${USER_KEY} ${FILE_S} ${CID} bearer_allow_all_user ${FILE_OTH_HEADER}
|
||||||
|
Get object ${USER_KEY} ${CID} ${S_OID_USER} bearer_allow_all_user local_file_eacl
|
||||||
Search object ${USER_KEY} ${CID} ${EMPTY} bearer_allow_all_user ${FILE_USR_HEADER} ${S_OBJ_H}
|
Search object ${USER_KEY} ${CID} ${EMPTY} bearer_allow_all_user ${FILE_USR_HEADER} ${S_OBJ_H}
|
||||||
Head object ${USER_KEY} ${CID} ${S_OID_USER} bearer_allow_all_user
|
Head object ${USER_KEY} ${CID} ${S_OID_USER} bearer_allow_all_user
|
||||||
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range bearer_allow_all_user 0:256
|
Get Range ${USER_KEY} ${CID} ${S_OID_USER} s_get_range bearer_allow_all_user 0:256
|
||||||
|
|
|
@ -36,19 +36,19 @@ NeoFS Simple Netmap
|
||||||
Validate Policy REP 1 IN LOC_PLACE CBF 1 SELECT 1 FROM LOC_SW AS LOC_PLACE FILTER Country EQ Sweden AS LOC_SW 1 @{EXPECTED}
|
Validate Policy REP 1 IN LOC_PLACE CBF 1 SELECT 1 FROM LOC_SW AS LOC_PLACE FILTER Country EQ Sweden AS LOC_SW 1 @{EXPECTED}
|
||||||
|
|
||||||
@{EXPECTED} = Create List s02.neofs.devenv:8080
|
@{EXPECTED} = Create List s02.neofs.devenv:8080
|
||||||
Validate Policy REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER City EQ 'Saint-Petersburg' AS LOC_SPB 1 @{EXPECTED}
|
Validate Policy REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER Location EQ 'Saint Petersburg (ex Leningrad)' AS LOC_SPB 1 @{EXPECTED}
|
||||||
|
|
||||||
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
|
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
|
||||||
Validate Policy REP 1 IN LOC_SPB_PLACE REP 1 IN LOC_MSK_PLACE CBF 1 SELECT 1 FROM LOC_SPB AS LOC_SPB_PLACE SELECT 1 FROM LOC_MSK AS LOC_MSK_PLACE FILTER City EQ 'Saint-Petersburg' AS LOC_SPB FILTER City EQ 'Moscow' AS LOC_MSK 2 @{EXPECTED}
|
Validate Policy REP 1 IN LOC_SPB_PLACE REP 1 IN LOC_MSK_PLACE CBF 1 SELECT 1 FROM LOC_SPB AS LOC_SPB_PLACE SELECT 1 FROM LOC_MSK AS LOC_MSK_PLACE FILTER Location EQ 'Saint Petersburg (ex Leningrad)' AS LOC_SPB FILTER Location EQ 'Moskva' AS LOC_MSK 2 @{EXPECTED}
|
||||||
|
|
||||||
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 s03.neofs.devenv:8080 s04.neofs.devenv:8080
|
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080 s03.neofs.devenv:8080 s04.neofs.devenv:8080
|
||||||
Validate Policy REP 4 CBF 1 SELECT 4 FROM LOC_EU FILTER Location EQ Europe AS LOC_EU 4 @{EXPECTED}
|
Validate Policy REP 4 CBF 1 SELECT 4 FROM LOC_EU FILTER Continent EQ Europe AS LOC_EU 4 @{EXPECTED}
|
||||||
|
|
||||||
@{EXPECTED} = Create List s02.neofs.devenv:8080
|
@{EXPECTED} = Create List s02.neofs.devenv:8080
|
||||||
Validate Policy REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER City NE 'Moscow' AND City NE 'Stockholm' AND City NE 'Helsinki' AS LOC_SPB 1 @{EXPECTED}
|
Validate Policy REP 1 CBF 1 SELECT 1 FROM LOC_SPB FILTER Location NE 'Moskva' AND Location NE 'Stockholm' AND Location NE 'Helsinki (Helsingfors)' AS LOC_SPB 1 @{EXPECTED}
|
||||||
|
|
||||||
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
|
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
|
||||||
Validate Policy REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER City NE 'Stockholm' AND City NE 'Helsinki' AS LOC_RU 2 @{EXPECTED}
|
Validate Policy REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER SubDivCode NE 'AB' AND SubDivCode NE '18' AS LOC_RU 2 @{EXPECTED}
|
||||||
|
|
||||||
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
|
@{EXPECTED} = Create List s01.neofs.devenv:8080 s02.neofs.devenv:8080
|
||||||
Validate Policy REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER Country EQ 'Russia' AS LOC_RU 2 @{EXPECTED}
|
Validate Policy REP 2 CBF 1 SELECT 2 FROM LOC_RU FILTER Country EQ 'Russia' AS LOC_RU 2 @{EXPECTED}
|
||||||
|
|
|
@ -7,7 +7,7 @@ Resource common_steps_object.robot
|
||||||
|
|
||||||
|
|
||||||
*** Test cases ***
|
*** Test cases ***
|
||||||
NeoFS Complex Object Operations
|
NeoFS Complex Storagegroup
|
||||||
[Documentation] Testcase to validate NeoFS operations with Storagegroup.
|
[Documentation] Testcase to validate NeoFS operations with Storagegroup.
|
||||||
[Tags] Object NeoFS NeoCLI
|
[Tags] Object NeoFS NeoCLI
|
||||||
[Timeout] 20 min
|
[Timeout] 20 min
|
||||||
|
@ -46,7 +46,7 @@ NeoFS Complex Object Operations
|
||||||
@{S_OBJ_ALL} = Create List ${S_OID_1} ${S_OID_2}
|
@{S_OBJ_ALL} = Create List ${S_OID_1} ${S_OID_2}
|
||||||
|
|
||||||
Log Storage group with 1 object
|
Log Storage group with 1 object
|
||||||
${SG_OID_1} = Put Storagegroup ${PRIV_KEY} ${CID} ${S_OID_1}
|
${SG_OID_1} = Put Storagegroup ${PRIV_KEY} ${CID} ${EMPTY} ${S_OID_1}
|
||||||
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1}
|
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1}
|
||||||
@{SPLIT_OBJ_1} = Get Split objects ${PRIV_KEY} ${CID} ${S_OID_1}
|
@{SPLIT_OBJ_1} = Get Split objects ${PRIV_KEY} ${CID} ${S_OID_1}
|
||||||
Get Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1} 70000000 @{SPLIT_OBJ_1}
|
Get Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1} 70000000 @{SPLIT_OBJ_1}
|
||||||
|
@ -58,7 +58,7 @@ NeoFS Complex Object Operations
|
||||||
|
|
||||||
|
|
||||||
Log Storage group with 2 objects
|
Log Storage group with 2 objects
|
||||||
${SG_OID_2} = Put Storagegroup ${PRIV_KEY} ${CID} @{S_OBJ_ALL}
|
${SG_OID_2} = Put Storagegroup ${PRIV_KEY} ${CID} ${EMPTY} @{S_OBJ_ALL}
|
||||||
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2}
|
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2}
|
||||||
@{SPLIT_OBJ_2} = Get Split objects ${PRIV_KEY} ${CID} ${S_OID_2}
|
@{SPLIT_OBJ_2} = Get Split objects ${PRIV_KEY} ${CID} ${S_OID_2}
|
||||||
@{SPLIT_OBJ_ALL} = Combine Lists ${SPLIT_OBJ_1} ${SPLIT_OBJ_2}
|
@{SPLIT_OBJ_ALL} = Combine Lists ${SPLIT_OBJ_1} ${SPLIT_OBJ_2}
|
||||||
|
@ -72,7 +72,7 @@ NeoFS Complex Object Operations
|
||||||
Log Incorrect input
|
Log Incorrect input
|
||||||
|
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Put Storagegroup ${PRIV_KEY} ${CID} ${UNEXIST_OID}
|
... Put Storagegroup ${PRIV_KEY} ${CID} ${EMPTY} ${UNEXIST_OID}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Delete Storagegroup ${PRIV_KEY} ${CID} ${UNEXIST_OID}
|
... Delete Storagegroup ${PRIV_KEY} ${CID} ${UNEXIST_OID}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ NeoFS Simple Storagegroup
|
||||||
@{S_OBJ_ALL} = Create List ${S_OID_1} ${S_OID_2}
|
@{S_OBJ_ALL} = Create List ${S_OID_1} ${S_OID_2}
|
||||||
|
|
||||||
Log Storage group with 1 object
|
Log Storage group with 1 object
|
||||||
${SG_OID_1} = Put Storagegroup ${PRIV_KEY} ${CID} ${S_OID_1}
|
${SG_OID_1} = Put Storagegroup ${PRIV_KEY} ${CID} ${EMPTY} ${S_OID_1}
|
||||||
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1}
|
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1}
|
||||||
Get Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1} 1024 ${S_OID_1}
|
Get Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1} 1024 ${S_OID_1}
|
||||||
${Tombstone} = Delete Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1}
|
${Tombstone} = Delete Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_1}
|
||||||
|
@ -57,7 +57,7 @@ NeoFS Simple Storagegroup
|
||||||
|
|
||||||
|
|
||||||
Log Storage group with 2 objects
|
Log Storage group with 2 objects
|
||||||
${SG_OID_2} = Put Storagegroup ${PRIV_KEY} ${CID} @{S_OBJ_ALL}
|
${SG_OID_2} = Put Storagegroup ${PRIV_KEY} ${CID} ${EMPTY} @{S_OBJ_ALL}
|
||||||
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2}
|
List Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2}
|
||||||
Get Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2} 2048 @{S_OBJ_ALL}
|
Get Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2} 2048 @{S_OBJ_ALL}
|
||||||
${Tombstone} = Delete Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2}
|
${Tombstone} = Delete Storagegroup ${PRIV_KEY} ${CID} ${SG_OID_2}
|
||||||
|
@ -69,7 +69,7 @@ NeoFS Simple Storagegroup
|
||||||
Log Incorrect input
|
Log Incorrect input
|
||||||
|
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Put Storagegroup ${PRIV_KEY} ${CID} ${UNEXIST_OID}
|
... Put Storagegroup ${PRIV_KEY} ${CID} ${EMPTY} ${UNEXIST_OID}
|
||||||
Run Keyword And Expect Error *
|
Run Keyword And Expect Error *
|
||||||
... Delete Storagegroup ${PRIV_KEY} ${CID} ${UNEXIST_OID}
|
... Delete Storagegroup ${PRIV_KEY} ${CID} ${UNEXIST_OID}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ NeoFS Deposit and Withdraw
|
||||||
|
|
||||||
Sleep 1 min
|
Sleep 1 min
|
||||||
|
|
||||||
Expexted Mainnet Balance ${ADDR} 4.85019610
|
Expexted Mainnet Balance ${ADDR} 4.85067180
|
||||||
${NEOFS_BALANCE} = Get Balance ${PRIV_KEY}
|
${NEOFS_BALANCE} = Get Balance ${PRIV_KEY}
|
||||||
|
|
||||||
${TX} = Withdraw Mainnet Gas ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
${TX} = Withdraw Mainnet Gas ${WALLET} ${ADDR} ${SCRIPT_HASH} 50
|
||||||
|
@ -40,7 +40,7 @@ NeoFS Deposit and Withdraw
|
||||||
Sleep 1 min
|
Sleep 1 min
|
||||||
Get Balance ${PRIV_KEY}
|
Get Balance ${PRIV_KEY}
|
||||||
Expected Balance ${PRIV_KEY} ${NEOFS_BALANCE} -50
|
Expected Balance ${PRIV_KEY} ${NEOFS_BALANCE} -50
|
||||||
Expexted Mainnet Balance ${ADDR} 54.81699450
|
Expexted Mainnet Balance ${ADDR} 54.81748270
|
||||||
|
|
||||||
[Teardown] Cleanup
|
[Teardown] Cleanup
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue