diff --git a/README.md b/README.md index 1be8c4a..94f4a27 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ The following UserScenarios and testcases are available for execution: * object_simple.robot * object_storagegroup_simple.robot * object_storagegroup_complex.robot + * object_expiration.robot * payment * withdraw.robot * services diff --git a/robot/resources/lib/neofs.py b/robot/resources/lib/neofs.py index c626fb7..201ce5c 100644 --- a/robot/resources/lib/neofs.py +++ b/robot/resources/lib/neofs.py @@ -182,20 +182,37 @@ def get_eacl(private_key: str, cid: str): raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) +@keyword('Get Epoch') +def get_epoch(private_key: str): + cmd = ( + f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} ' + f'netmap epoch' + ) + logger.info(f"Cmd: {cmd}") + try: + complProc = subprocess.run(cmd, check=True, universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True) + output = complProc.stdout + logger.info(f"Output: {output}") + return int(output) + except subprocess.CalledProcessError as e: + raise Exception(f"command '{e.cmd}' return with error (code {e.returncode}): {e.output}") @keyword('Set eACL') def set_eacl(private_key: str, cid: str, eacl: str, add_keys: str = ""): file_path = TEMP_DIR + eacl - - Cmd = ( + cmd = ( f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} ' f'container set-eacl --cid {cid} --table {file_path} {add_keys}' ) - 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) + logger.info(f"Cmd: {cmd}") + try: + complProc = subprocess.run(cmd, check=True, universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True) + output = complProc.stdout + logger.info(f"Output: {output}") + except subprocess.CalledProcessError as e: + raise Exception(f"command '{e.cmd}' return with error (code {e.returncode}): {e.output}") @keyword('Form BearerToken file') def form_bearertoken_file(private_key: str, cid: str, file_name: str, eacl_oper_list, @@ -851,6 +868,7 @@ def put_object(private_key: str, path: str, cid: str, bearer: str, user_headers: if user_headers: user_headers = f"--attributes {user_headers}" + if bearer: bearer = f"--bearer {TEMP_DIR}{bearer}" diff --git a/robot/testsuites/integration/object/common_steps_object.robot b/robot/testsuites/integration/object/common_steps_object.robot index f932608..ff0eb75 100644 --- a/robot/testsuites/integration/object/common_steps_object.robot +++ b/robot/testsuites/integration/object/common_steps_object.robot @@ -1,7 +1,44 @@ *** Variables *** -${FILE_USR_HEADER} = key1=1,key2=abc +${FILE_USR_HEADER} = key1=1,key2=abc ${FILE_USR_HEADER_OTH} = key1=2 -${UNEXIST_OID} = 256ZZZZZZZZZZZZZZZZAAAAAAAAAAAAAAAAAAAAAAAAA +${UNEXIST_OID} = B2DKvkHnLnPvapbDgfpU1oVUPuXQo5LTfKVxmNDZXQff +${TRANSFER_AMOUNT} = 15 +${DEPOSIT_AMOUNT} = 10 *** Keywords *** +Payment operations + ${WALLET} = Init wallet + Generate wallet ${WALLET} + ${ADDR} = Dump Address ${WALLET} + ${PRIV_KEY} = Dump PrivKey ${WALLET} ${ADDR} + ${TX} = Transfer Mainnet Gas ${MAINNET_WALLET_PATH} ${DEF_WALLET_ADDR} ${ADDR} ${TRANSFER_AMOUNT} + + Wait Until Keyword Succeeds ${BASENET_WAIT_TIME} ${BASENET_BLOCK_TIME} + ... Transaction accepted in block ${TX} + Get Transaction ${TX} + Expected Mainnet Balance ${ADDR} ${TRANSFER_AMOUNT} + + ${SCRIPT_HASH} = Get ScriptHash ${PRIV_KEY} + + ${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} ${DEPOSIT_AMOUNT} + Wait Until Keyword Succeeds ${BASENET_WAIT_TIME} ${BASENET_BLOCK_TIME} + ... Transaction accepted in block ${TX_DEPOSIT} + Get Transaction ${TX_DEPOSIT} + + ${BALANCE} = Wait Until Keyword Succeeds ${NEOFS_EPOCH_TIMEOUT} ${MORPH_BLOCK_TIME} + ... Expected Balance ${PRIV_KEY} 0 ${DEPOSIT_AMOUNT} + + Set Global Variable ${PRIV_KEY} ${PRIV_KEY} + Set Global Variable ${ADDR} ${ADDR} + + +Prepare container + ${CID} = Create container ${PRIV_KEY} + Container Existing ${PRIV_KEY} ${CID} + + Wait Until Keyword Succeeds ${NEOFS_EPOCH_TIMEOUT} ${MORPH_BLOCK_TIME} + ... Expected Balance ${PRIV_KEY} ${DEPOSIT_AMOUNT} ${NEOFS_CREATE_CONTAINER_GAS_FEE} + + Set Global Variable ${CID} ${CID} + \ No newline at end of file diff --git a/robot/testsuites/integration/object/object_complex.robot b/robot/testsuites/integration/object/object_complex.robot index aa7fe24..3ca5887 100644 --- a/robot/testsuites/integration/object/object_complex.robot +++ b/robot/testsuites/integration/object/object_complex.robot @@ -12,31 +12,8 @@ NeoFS Complex Object Operations [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 ${DEF_WALLET_ADDR} ${ADDR} 15 - Wait Until Keyword Succeeds 1 min 15 sec - ... Transaction accepted in block ${TX} - Get Transaction ${TX} - Expected Mainnet Balance ${ADDR} 15 - - ${SCRIPT_HASH} = Get ScriptHash ${PRIV_KEY} - - ${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 10 - 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 10 - - ${CID} = Create container ${PRIV_KEY} - Container Existing ${PRIV_KEY} ${CID} - - Wait Until Keyword Succeeds 2 min 30 sec - ... Expected Balance ${PRIV_KEY} 10 -1e-08 + Payment operations + Prepare container ${FILE} = Generate file of bytes ${COMPLEX_OBJ_SIZE} ${FILE_HASH} = Get file hash ${FILE} diff --git a/robot/testsuites/integration/object/object_expiration.robot b/robot/testsuites/integration/object/object_expiration.robot new file mode 100644 index 0000000..cdef4a8 --- /dev/null +++ b/robot/testsuites/integration/object/object_expiration.robot @@ -0,0 +1,73 @@ +*** Settings *** +Variables ../../../variables/common.py + +Library ../${RESOURCES}/neofs.py +Library ../${RESOURCES}/payment_neogo.py +Resource common_steps_object.robot + + +*** Test cases *** +NeoFS Simple Object Operations + [Documentation] Testcase to validate NeoFS object expiration option. + [Tags] Object NeoFS NeoCLI + [Timeout] 20 min + + Payment operations + Prepare container + + ${FILE} = Generate file of bytes ${SIMPLE_OBJ_SIZE} + ${FILE_HASH} = Get file hash ${FILE} + + ${EPOCH} = Get Epoch ${PRIV_KEY} + + ${EPOCH_PRE} = Evaluate ${EPOCH}-1 + ${EPOCH_NEXT} = Evaluate ${EPOCH}+1 + ${EPOCH_POST} = Evaluate ${EPOCH}+1000 + + # Failed on attempt to create epoch from the past + Run Keyword And Expect Error * + ... Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH_PRE} + + # Put object with different expiration epoch numbers (current, next, and from the distant future) + ${OID_CUR} = Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH} + ${OID_NXT} = Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH_NEXT} + ${OID_PST} = Put object ${PRIV_KEY} ${FILE} ${CID} ${EMPTY} __NEOFS__EXPIRATION_EPOCH=${EPOCH_POST} + + # Check objects for existence + Get object ${PRIV_KEY} ${CID} ${OID_CUR} ${EMPTY} file_read_cur + Get object ${PRIV_KEY} ${CID} ${OID_NXT} ${EMPTY} file_read_nxt + Get object ${PRIV_KEY} ${CID} ${OID_PST} ${EMPTY} file_read_pst + + # Wait one epoch to check that expired objects (OID_CUR) will be removed + Sleep ${NEOFS_EPOCH_TIMEOUT} + + Run Keyword And Expect Error * + ... Get object ${PRIV_KEY} ${CID} ${OID_CUR} ${EMPTY} file_read + + # Check that correct object with expiration in the future is existed + Get object ${PRIV_KEY} ${CID} ${OID_NXT} ${EMPTY} file_read + Get object ${PRIV_KEY} ${CID} ${OID_PST} ${EMPTY} file_read_pst + + # Wait one more epoch to check that expired object (OID_NXT) will be removed + Sleep ${NEOFS_EPOCH_TIMEOUT} + + Run Keyword And Expect Error * + ... Get object ${PRIV_KEY} ${CID} ${OID_NXT} ${EMPTY} file_read + + # Check that correct object with expiration in the distant future is existed + Get object ${PRIV_KEY} ${CID} ${OID_PST} ${EMPTY} file_read_pst + + [Teardown] Cleanup + + + +*** Keywords *** + +Cleanup + Cleanup Files + Get Docker Logs object_expiration + + + + + diff --git a/robot/testsuites/integration/object/object_simple.robot b/robot/testsuites/integration/object/object_simple.robot index 07bc867..84fb56e 100644 --- a/robot/testsuites/integration/object/object_simple.robot +++ b/robot/testsuites/integration/object/object_simple.robot @@ -10,33 +10,10 @@ Resource common_steps_object.robot NeoFS Simple Object Operations [Documentation] Testcase to validate NeoFS operations with simple object. [Tags] Object NeoFS NeoCLI - [Timeout] 20 min + [Timeout] 10 min - ${WALLET} = Init wallet - Generate wallet ${WALLET} - ${ADDR} = Dump Address ${WALLET} - ${PRIV_KEY} = Dump PrivKey ${WALLET} ${ADDR} - ${TX} = Transfer Mainnet Gas wallets/wallet.json ${DEF_WALLET_ADDR} ${ADDR} 15 - Wait Until Keyword Succeeds 1 min 15 sec - ... Transaction accepted in block ${TX} - Get Transaction ${TX} - Expected Mainnet Balance ${ADDR} 15 - - ${SCRIPT_HASH} = Get ScriptHash ${PRIV_KEY} - - ${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 10 - 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 10 - - ${CID} = Create container ${PRIV_KEY} - Container Existing ${PRIV_KEY} ${CID} - - Wait Until Keyword Succeeds 2 min 30 sec - ... Expected Balance ${PRIV_KEY} 10 -1e-08 + Payment operations + Prepare container ${FILE} = Generate file of bytes ${SIMPLE_OBJ_SIZE} ${FILE_HASH} = Get file hash ${FILE} diff --git a/robot/testsuites/integration/object/object_storagegroup_complex.robot b/robot/testsuites/integration/object/object_storagegroup_complex.robot index 25ec55a..682064b 100644 --- a/robot/testsuites/integration/object/object_storagegroup_complex.robot +++ b/robot/testsuites/integration/object/object_storagegroup_complex.robot @@ -12,31 +12,11 @@ NeoFS Complex Storagegroup [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 ${DEF_WALLET_ADDR} ${ADDR} 15 - Wait Until Keyword Succeeds 1 min 15 sec - ... Transaction accepted in block ${TX} - Get Transaction ${TX} - Expected Mainnet Balance ${ADDR} 15 + Payment operations + Create container - ${SCRIPT_HASH} = Get ScriptHash ${PRIV_KEY} - - ${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 10 - 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 10 - - ${CID} = Create container ${PRIV_KEY} - Container Existing ${PRIV_KEY} ${CID} - - ${FILE_S} = Generate file of bytes ${COMPLEX_OBJ_SIZE} - ${FILE_HASH_S} = Get file hash ${FILE_S} + ${FILE_S} = Generate file of bytes ${COMPLEX_OBJ_SIZE} + ${FILE_HASH_S} = Get file hash ${FILE_S} # Put two Simple Object diff --git a/robot/testsuites/integration/object/object_storagegroup_simple.robot b/robot/testsuites/integration/object/object_storagegroup_simple.robot index 544f112..25c3df8 100644 --- a/robot/testsuites/integration/object/object_storagegroup_simple.robot +++ b/robot/testsuites/integration/object/object_storagegroup_simple.robot @@ -12,31 +12,11 @@ NeoFS Simple Storagegroup [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 ${DEF_WALLET_ADDR} ${ADDR} 15 - Wait Until Keyword Succeeds 1 min 15 sec - ... Transaction accepted in block ${TX} - Get Transaction ${TX} - Expected Mainnet Balance ${ADDR} 15 + Payment operations + Create container - ${SCRIPT_HASH} = Get ScriptHash ${PRIV_KEY} - - ${TX_DEPOSIT} = NeoFS Deposit ${WALLET} ${ADDR} ${SCRIPT_HASH} 10 - 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 10 - - ${CID} = Create container ${PRIV_KEY} - Container Existing ${PRIV_KEY} ${CID} - - ${FILE_S} = Generate file of bytes ${SIMPLE_OBJ_SIZE} - ${FILE_HASH_S} = Get file hash ${FILE_S} + ${FILE_S} = Generate file of bytes ${SIMPLE_OBJ_SIZE} + ${FILE_HASH_S} = Get file hash ${FILE_S} # Put two Simple Object diff --git a/robot/variables/common.py b/robot/variables/common.py index 4265faa..98023d5 100644 --- a/robot/variables/common.py +++ b/robot/variables/common.py @@ -9,9 +9,14 @@ CERT="%s/../../ca" % ROOT # in case when test is run from root in docker ABSOLUTE_FILE_PATH="/robot/testsuites/integration" # Price of the contract Deposit/Withdraw execution: +MAINNET_WALLET_PATH = "wallets/wallet.json" NEOFS_CONTRACT_DEPOSIT_GAS_FEE = 0.1679897 NEOFS_CONTRACT_WITHDRAW_GAS_FEE = 0.0382514 +NEOFS_CREATE_CONTAINER_GAS_FEE = -1e-08 NEOFS_EPOCH_TIMEOUT = "5min" +BASENET_BLOCK_TIME = "15s" +BASENET_WAIT_TIME = "1min" +MORPH_BLOCK_TIME = "1s" NEOFS_CONTRACT_CACHE_TIMEOUT = "30s" NEOFS_IR_WIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY" NEOFS_SN_WIF = "Kwk6k2eC3L3QuPvD8aiaNyoSXgQ2YL1bwS5CP1oKoA9waeAze97s"