From 60c9e770733aefab56fd3c4529779ad62024c83a Mon Sep 17 00:00:00 2001 From: alexstroke <111361420+astrokov7@users.noreply.github.com> Date: Mon, 12 Feb 2024 18:25:59 +0100 Subject: [PATCH] [refactor] migrate integration Rust tests to client cli pytests Signed-off-by: alexstroke <111361420+astrokov7@users.noreply.github.com> --- client/tests/integration/asset.rs | 12 ++ ...d_account.rs => deprecated_add_account.rs} | 4 + ...add_domain.rs => deprecated_add_domain.rs} | 4 + ...ion.rs => deprecated_asset_propagation.rs} | 4 + ...n_owner.rs => domain_owner_permissions.rs} | 0 .../{ => extra_functional}/connected_peers.rs | 0 .../deprecated_config.rs} | 5 + .../tests/integration/extra_functional/mod.rs | 7 + .../multiple_blocks_created.rs | 0 .../{ => extra_functional}/offline_peers.rs | 0 .../{ => extra_functional}/restart_peer.rs | 0 .../{ => extra_functional}/unregister_peer.rs | 0 .../unstable_network.rs | 0 client/tests/integration/mod.rs | 17 +- client/tests/integration/queries/mod.rs | 1 + .../integration/{ => queries}/query_errors.rs | 0 client/tests/integration/transfer_asset.rs | 10 +- client_cli/pytests/common/consts.py | 5 +- client_cli/pytests/common/helpers.py | 54 +++++- .../json_isi_examples/unregister_asset.json | 7 + client_cli/pytests/common/settings.py | 2 + client_cli/pytests/models/account.py | 3 +- client_cli/pytests/models/asset.py | 4 + client_cli/pytests/models/domain.py | 1 + client_cli/pytests/src/client_cli/__init__.py | 2 +- .../pytests/src/client_cli/client_cli.py | 145 +++++++++++----- .../pytests/src/client_cli/configuration.py | 52 ++++-- client_cli/pytests/src/client_cli/have.py | 24 ++- client_cli/pytests/src/client_cli/iroha.py | 29 ++-- client_cli/pytests/src/client_cli/match.py | 1 + client_cli/pytests/test/__init__.py | 36 ++-- client_cli/pytests/test/accounts/conftest.py | 19 +-- .../accounts/test_accounts_query_filters.py | 16 +- .../test/accounts/test_register_accounts.py | 49 +++--- .../test/accounts/test_set_key_value_pair.py | 9 +- client_cli/pytests/test/assets/conftest.py | 27 ++- .../test/assets/test_assets_query_filters.py | 4 +- .../pytests/test/assets/test_burn_assets.py | 6 +- .../pytests/test/assets/test_mint_assets.py | 60 +++++-- .../assets/test_register_asset_definitions.py | 78 ++++++--- .../test/assets/test_transfer_assets.py | 57 ++++++- .../test/assets/test_unregister_asset.py | 26 +++ client_cli/pytests/test/atomicity/conftest.py | 6 +- ...ultiple_instructions_within_transaction.py | 1 + ...st_pair_instructions_within_transaction.py | 1 + ...t_wrong_instructions_within_transaction.py | 1 + client_cli/pytests/test/conftest.py | 158 ++++++++++++++---- client_cli/pytests/test/domains/conftest.py | 23 +-- .../domains/test_domains_query_filters.py | 8 +- .../test/domains/test_register_domains.py | 18 +- .../test/domains/test_transfer_domains.py | 17 +- client_cli/pytests/test/roles/conftest.py | 9 +- .../pytests/test/roles/test_register_roles.py | 7 +- client_cli/pytests/test/triggers/conftest.py | 9 + .../test/triggers/test_register_trigger.py | 22 +++ 55 files changed, 761 insertions(+), 299 deletions(-) rename client/tests/integration/{add_account.rs => deprecated_add_account.rs} (90%) rename client/tests/integration/{add_domain.rs => deprecated_add_domain.rs} (89%) rename client/tests/integration/{asset_propagation.rs => deprecated_asset_propagation.rs} (94%) rename client/tests/integration/{domain_owner.rs => domain_owner_permissions.rs} (100%) rename client/tests/integration/{ => extra_functional}/connected_peers.rs (100%) rename client/tests/integration/{config.rs => extra_functional/deprecated_config.rs} (88%) create mode 100644 client/tests/integration/extra_functional/mod.rs rename client/tests/integration/{ => extra_functional}/multiple_blocks_created.rs (100%) rename client/tests/integration/{ => extra_functional}/offline_peers.rs (100%) rename client/tests/integration/{ => extra_functional}/restart_peer.rs (100%) rename client/tests/integration/{ => extra_functional}/unregister_peer.rs (100%) rename client/tests/integration/{ => extra_functional}/unstable_network.rs (100%) rename client/tests/integration/{ => queries}/query_errors.rs (100%) create mode 100644 client_cli/pytests/common/json_isi_examples/unregister_asset.json create mode 100644 client_cli/pytests/test/assets/test_unregister_asset.py create mode 100644 client_cli/pytests/test/triggers/conftest.py create mode 100644 client_cli/pytests/test/triggers/test_register_trigger.py diff --git a/client/tests/integration/asset.rs b/client/tests/integration/asset.rs index 2758c751962..136dac7446f 100644 --- a/client/tests/integration/asset.rs +++ b/client/tests/integration/asset.rs @@ -11,6 +11,10 @@ use iroha_primitives::fixed::Fixed; use serde_json::json; use test_network::*; +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test is deprecated and refers to test_register_asset_definitions.py" +)] #[test] fn client_register_asset_should_add_asset_once_but_not_twice() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(10_620).start_with_runtime(); @@ -89,6 +93,10 @@ fn unregister_asset_should_remove_asset_from_account() -> Result<()> { } #[test] +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test is deprecated and refers to test_mint_assets.py" +)] fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(10_000).start_with_runtime(); wait_for_genesis_committed(&[test_client.clone()], 0); @@ -202,6 +210,10 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { } #[test] +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test is deprecated and refers to test_register_asset_definitions.py" +)] fn client_add_asset_with_name_length_more_than_limit_should_not_commit_transaction() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(10_520).start_with_runtime(); wait_for_genesis_committed(&[test_client.clone()], 0); diff --git a/client/tests/integration/add_account.rs b/client/tests/integration/deprecated_add_account.rs similarity index 90% rename from client/tests/integration/add_account.rs rename to client/tests/integration/deprecated_add_account.rs index d46b3bb65af..8972f7ad05c 100644 --- a/client/tests/integration/add_account.rs +++ b/client/tests/integration/deprecated_add_account.rs @@ -5,6 +5,10 @@ use iroha_client::{client, data_model::prelude::*}; use iroha_config::iroha::Configuration; use test_network::*; +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test suite is deprecated and refers to test_register_accounts.py" +)] #[test] fn client_add_account_with_name_length_more_than_limit_should_not_commit_transaction() -> Result<()> { diff --git a/client/tests/integration/add_domain.rs b/client/tests/integration/deprecated_add_domain.rs similarity index 89% rename from client/tests/integration/add_domain.rs rename to client/tests/integration/deprecated_add_domain.rs index bb889c25c15..5fe11bceb00 100644 --- a/client/tests/integration/add_domain.rs +++ b/client/tests/integration/deprecated_add_domain.rs @@ -5,6 +5,10 @@ use iroha_client::{client, data_model::prelude::*}; use iroha_config::iroha::Configuration; use test_network::*; +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test suite is deprecated and refers totest_register_domains.py" +)] #[test] fn client_add_domain_with_name_length_more_than_limit_should_not_commit_transaction() -> Result<()> { diff --git a/client/tests/integration/asset_propagation.rs b/client/tests/integration/deprecated_asset_propagation.rs similarity index 94% rename from client/tests/integration/asset_propagation.rs rename to client/tests/integration/deprecated_asset_propagation.rs index d248d160f86..b9761931565 100644 --- a/client/tests/integration/asset_propagation.rs +++ b/client/tests/integration/deprecated_asset_propagation.rs @@ -12,6 +12,10 @@ use iroha_client::{ use iroha_config::iroha::Configuration; use test_network::*; +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test is deprecated and refers to test_mint_asset.py" +)] #[test] fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_another_peer( ) -> Result<()> { diff --git a/client/tests/integration/domain_owner.rs b/client/tests/integration/domain_owner_permissions.rs similarity index 100% rename from client/tests/integration/domain_owner.rs rename to client/tests/integration/domain_owner_permissions.rs diff --git a/client/tests/integration/connected_peers.rs b/client/tests/integration/extra_functional/connected_peers.rs similarity index 100% rename from client/tests/integration/connected_peers.rs rename to client/tests/integration/extra_functional/connected_peers.rs diff --git a/client/tests/integration/config.rs b/client/tests/integration/extra_functional/deprecated_config.rs similarity index 88% rename from client/tests/integration/config.rs rename to client/tests/integration/extra_functional/deprecated_config.rs index 1c71aba683d..0fef86fcf33 100644 --- a/client/tests/integration/config.rs +++ b/client/tests/integration/extra_functional/deprecated_config.rs @@ -1,6 +1,11 @@ use iroha_client::data_model::Level; use test_network::*; +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test is meaningless since it doesn't test anything useful" +)] +#[ignore = "ignore, more in #4094"] #[test] fn config_endpoints() { const NEW_LOG_LEVEL: Level = Level::ERROR; diff --git a/client/tests/integration/extra_functional/mod.rs b/client/tests/integration/extra_functional/mod.rs new file mode 100644 index 00000000000..773ccaca0d4 --- /dev/null +++ b/client/tests/integration/extra_functional/mod.rs @@ -0,0 +1,7 @@ +mod connected_peers; +mod deprecated_config; +mod multiple_blocks_created; +mod offline_peers; +mod restart_peer; +mod unregister_peer; +mod unstable_network; diff --git a/client/tests/integration/multiple_blocks_created.rs b/client/tests/integration/extra_functional/multiple_blocks_created.rs similarity index 100% rename from client/tests/integration/multiple_blocks_created.rs rename to client/tests/integration/extra_functional/multiple_blocks_created.rs diff --git a/client/tests/integration/offline_peers.rs b/client/tests/integration/extra_functional/offline_peers.rs similarity index 100% rename from client/tests/integration/offline_peers.rs rename to client/tests/integration/extra_functional/offline_peers.rs diff --git a/client/tests/integration/restart_peer.rs b/client/tests/integration/extra_functional/restart_peer.rs similarity index 100% rename from client/tests/integration/restart_peer.rs rename to client/tests/integration/extra_functional/restart_peer.rs diff --git a/client/tests/integration/unregister_peer.rs b/client/tests/integration/extra_functional/unregister_peer.rs similarity index 100% rename from client/tests/integration/unregister_peer.rs rename to client/tests/integration/extra_functional/unregister_peer.rs diff --git a/client/tests/integration/unstable_network.rs b/client/tests/integration/extra_functional/unstable_network.rs similarity index 100% rename from client/tests/integration/unstable_network.rs rename to client/tests/integration/extra_functional/unstable_network.rs diff --git a/client/tests/integration/mod.rs b/client/tests/integration/mod.rs index 8c8008ce649..c802fb6e1fc 100644 --- a/client/tests/integration/mod.rs +++ b/client/tests/integration/mod.rs @@ -1,22 +1,17 @@ -mod add_account; -mod add_domain; mod asset; -mod asset_propagation; mod burn_public_keys; -mod config; -mod connected_peers; -mod domain_owner; +mod deprecated_add_account; +mod deprecated_add_domain; +mod deprecated_asset_propagation; +mod domain_owner_permissions; mod events; -mod multiple_blocks_created; +mod extra_functional; mod multisignature_account; mod multisignature_transaction; mod non_mintable; -mod offline_peers; mod pagination; mod permissions; mod queries; -mod query_errors; -mod restart_peer; mod roles; mod set_parameter; mod sorting; @@ -24,6 +19,4 @@ mod transfer_asset; mod triggers; mod tx_history; mod tx_rollback; -mod unregister_peer; -mod unstable_network; mod upgrade; diff --git a/client/tests/integration/queries/mod.rs b/client/tests/integration/queries/mod.rs index d654c8fc83b..d4ed9a45cd6 100644 --- a/client/tests/integration/queries/mod.rs +++ b/client/tests/integration/queries/mod.rs @@ -12,6 +12,7 @@ use test_network::*; mod account; mod asset; +mod query_errors; mod role; #[test] diff --git a/client/tests/integration/query_errors.rs b/client/tests/integration/queries/query_errors.rs similarity index 100% rename from client/tests/integration/query_errors.rs rename to client/tests/integration/queries/query_errors.rs diff --git a/client/tests/integration/transfer_asset.rs b/client/tests/integration/transfer_asset.rs index be37310c5cd..100fb1df07d 100644 --- a/client/tests/integration/transfer_asset.rs +++ b/client/tests/integration/transfer_asset.rs @@ -6,6 +6,10 @@ use iroha_client::{ use iroha_primitives::fixed::Fixed; use test_network::*; +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test suite is deprecated and refers to test_tranfer_assets.py" +)] #[test] fn simulate_transfer_quantity() { simulate_transfer( @@ -42,8 +46,12 @@ fn simulate_transfer_fixed() { ) } +#[deprecated( + since = "2.0.0-pre-rc.20", + note = "This test suite is deprecated, use test_tranfer_assets.py instead" +)] +#[ignore = "migrated to client cli python tests"] #[test] -#[ignore = "long"] #[should_panic(expected = "insufficient funds")] fn simulate_insufficient_funds() { simulate_transfer( diff --git a/client_cli/pytests/common/consts.py b/client_cli/pytests/common/consts.py index 6987c4b9d41..b5183a2750e 100644 --- a/client_cli/pytests/common/consts.py +++ b/client_cli/pytests/common/consts.py @@ -22,7 +22,8 @@ class Stderr(Enum): INVALID_VALUE_TYPE = 'Matching variant not found' RESERVED_CHARACTER = 'The `@` character is reserved for `account@domain` constructs,' \ ' `#` — for `asset#domain` and `$` — for `trigger$domain`.' - WHITESPACES = "White space not allowed" + WHITESPACES = 'White space not allowed' + INSUFFICIENT_FUNDS = 'Not enough quantity to transfer/burn' class ReservedChars(Enum): @@ -40,6 +41,6 @@ class ValueTypes(Enum): """ QUANTITY = 'Quantity' # unsigned 32-bit integer STORE = 'Store' #storing key-values in object's metadata - # BIG_QUANTITY = 'BigQuantity' unsigned 128-bit integer + BIG_QUANTITY = 'BigQuantity' #unsigned 128-bit integer # FIXED = 'Fixed' 64-bit fixed-precision number with # nine significant digits after the decimal point diff --git a/client_cli/pytests/common/helpers.py b/client_cli/pytests/common/helpers.py index f63b11dfc86..2188d478ec7 100644 --- a/client_cli/pytests/common/helpers.py +++ b/client_cli/pytests/common/helpers.py @@ -3,14 +3,65 @@ """ import binascii +import json +import os import random +import re import string from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey + from common.consts import ReservedChars, fake +def extract_hash(stdout): + """ + Extracts a SHA-256 hash from the given string. + + :param stdout: The string from which to extract the hash. + :return: The extracted hash if found, otherwise None. + """ + if not isinstance(stdout, str) or not stdout.strip(): + return None + pattern = r'"([A-Fa-f0-9]{64})"' + match = re.search(pattern, stdout) + return match.group(1) if match else None + +def get_peers_config_files(path_to_configs): + """ + Returns a list of config file paths from the given directory. + """ + config_files = [] + for entry in os.listdir(path_to_configs): + if entry.endswith('.json') and 'config_to_peer' in entry: + config_files.append(os.path.join(path_to_configs, entry)) + return config_files + +def read_isi_from_json(file_path): + """ + Reads ISI instruction from a JSON file. + + :param file_path: Path to the JSON file containing ISI instruction. + :return: Dictionary with ISI instruction. + """ + with open(file_path, 'r', encoding='utf-8') as file: + isi_data = json.load(file) + return isi_data + + +def write_isi_to_json(isi_data, file_path): + """ + Writes ISI instruction to a JSON file. + + :param isi_data: Dictionary with ISI instruction. + :param file_path: Path to save the JSON file. + """ + if not isinstance(isi_data, list): + isi_data = [isi_data] + with open(file_path, 'w', encoding='utf-8') as file: + json.dump(isi_data, file, indent=4) + def generate_random_string_with_reserved_char(): """ Generate a random string with a reserved character. @@ -55,7 +106,8 @@ def generate_random_string_without_reserved_chars(length): """ Generate a random string with the specified length, excluding reserved characters. """ - allowed_chars = [c for c in [*string.ascii_letters, *string.digits] if c not in ReservedChars.ALL.value] + allowed_chars = \ + [c for c in [*string.ascii_letters, *string.digits] if c not in ReservedChars.ALL.value] return generate_random_string(length, allowed_chars) diff --git a/client_cli/pytests/common/json_isi_examples/unregister_asset.json b/client_cli/pytests/common/json_isi_examples/unregister_asset.json new file mode 100644 index 00000000000..ac3d7f314f9 --- /dev/null +++ b/client_cli/pytests/common/json_isi_examples/unregister_asset.json @@ -0,0 +1,7 @@ +[{ +"Unregister": { + "Asset": { + "object_id": "rose#alice@wonderland" + } +} +}] \ No newline at end of file diff --git a/client_cli/pytests/common/settings.py b/client_cli/pytests/common/settings.py index c79aa7765f2..81dd124c191 100644 --- a/client_cli/pytests/common/settings.py +++ b/client_cli/pytests/common/settings.py @@ -4,6 +4,7 @@ """ import os + from dotenv import load_dotenv load_dotenv() @@ -17,6 +18,7 @@ PATH_CONFIG_CLIENT_CLI = os.path.join(ROOT_DIR, "config.json") CLIENT_CLI_PATH = os.path.join(ROOT_DIR, "iroha_client_cli") +PEERS_CONFIGS_PATH = os.path.join(ROOT_DIR, "peers_configs") PORT_MIN = int(os.getenv('TORII_API_PORT_MIN', '8080')) PORT_MAX = int(os.getenv('TORII_API_PORT_MAX', '8083')) diff --git a/client_cli/pytests/models/account.py b/client_cli/pytests/models/account.py index 0dd65575948..b191dbbbcfd 100644 --- a/client_cli/pytests/models/account.py +++ b/client_cli/pytests/models/account.py @@ -3,6 +3,7 @@ """ from dataclasses import dataclass + @dataclass class Account: """ @@ -17,7 +18,7 @@ class Account: """ name: str domain: str - public_key: str + public_key: str = None def __repr__(self): return f"{self.name}@{self.domain}" diff --git a/client_cli/pytests/models/asset.py b/client_cli/pytests/models/asset.py index 2ca532c4a6d..8b4fff03363 100644 --- a/client_cli/pytests/models/asset.py +++ b/client_cli/pytests/models/asset.py @@ -4,6 +4,7 @@ from dataclasses import dataclass + @dataclass class AssetDefinition: """ @@ -39,10 +40,13 @@ class Asset: :param definition: The asset definition of the asset. :type definition: AssetDefinition + :param account: The account of the asset. + :type definition: str :param value: The value of the asset. :type value: str """ definition: AssetDefinition + account: str value: str def __repr__(self): diff --git a/client_cli/pytests/models/domain.py b/client_cli/pytests/models/domain.py index cf3528ba338..6f1111c5879 100644 --- a/client_cli/pytests/models/domain.py +++ b/client_cli/pytests/models/domain.py @@ -3,6 +3,7 @@ """ from dataclasses import dataclass + @dataclass class Domain: """ diff --git a/client_cli/pytests/src/client_cli/__init__.py b/client_cli/pytests/src/client_cli/__init__.py index f907e8b5009..dd9bea09b2a 100644 --- a/client_cli/pytests/src/client_cli/__init__.py +++ b/client_cli/pytests/src/client_cli/__init__.py @@ -2,7 +2,7 @@ This module initializes the Iroha client and configuration using environment variables. """ -from common.settings import PATH_CONFIG_CLIENT_CLI, PORT_MIN, PORT_MAX +from common.settings import PATH_CONFIG_CLIENT_CLI, PORT_MAX, PORT_MIN from src.client_cli.client_cli import ClientCli from src.client_cli.configuration import Config from src.client_cli.iroha import Iroha diff --git a/client_cli/pytests/src/client_cli/client_cli.py b/client_cli/pytests/src/client_cli/client_cli.py index cdd33b58c59..065be98ce1a 100644 --- a/client_cli/pytests/src/client_cli/client_cli.py +++ b/client_cli/pytests/src/client_cli/client_cli.py @@ -2,14 +2,17 @@ This module contains the ClientCli class, which is responsible for building and executing commands for interacting with Iroha blockchain using the Iroha command-line client. """ -import json +import shlex import subprocess -from time import sleep, monotonic +from pathlib import Path +from time import monotonic, sleep from typing import Callable import allure -from common.settings import PATH_CONFIG_CLIENT_CLI, CLIENT_CLI_PATH +from common.helpers import extract_hash, read_isi_from_json, write_isi_to_json +from common.settings import (BASE_DIR, CLIENT_CLI_PATH, PATH_CONFIG_CLIENT_CLI, + ROOT_DIR) from src.client_cli.configuration import Config @@ -32,7 +35,8 @@ def __init__(self, config: Config): self.command = [self.BASE_PATH] + self.BASE_FLAGS self.stdout = None self.stderr = None - self._timeout = 5 + self.transaction_hash = None + self._timeout = 20 def __enter__(self): """ @@ -64,8 +68,9 @@ def wait_for(self, condition: Callable[[], bool], timeout=None): start_time = monotonic() while not condition(): if monotonic() - start_time > timeout: - raise TimeoutError(f"Expected condition to be satisfied after waiting for '{timeout}' seconds.") - sleep(0.5) + raise TimeoutError( + f"Expected condition to be satisfied after waiting for '{timeout}' seconds.") + sleep(0.25) def reset(self): """ @@ -106,16 +111,14 @@ def list_all(self): self.command.append('all') return self - def list_filter(self, filter): + def list_filter(self, filter_criteria): """ - Appends the 'list all' command to the command list. - - :return: The current ClientCli object. - :rtype: ClientCli + Appends the 'list filter' command to the command list. + :param filter_criteria: Criteria to filter the list. """ - self.command.append('list'), + self.command.append('list') self.command.append('filter') - self.command.append(filter) + self.command.append(filter_criteria) return self def domain(self, domain: str): @@ -156,9 +159,9 @@ def asset(self, asset_definition=None, account=None, value_of_value_type=None): Executes the 'asset' command with the given asset definition, account, and value. :param asset_definition: The asset definition to be queried, defaults to None. - :type asset_definition: AssetDefinition, optional + :type asset_definition: AssetDefinition :param account: The account to be queried, defaults to None. - :type account: Account, optional + :type account: Account :param value_of_value_type: The value of the value type, defaults to None. :type value_of_value_type: str, optional :return: The current ClientCli object. @@ -236,6 +239,51 @@ def definition(self, asset: str, domain: str, value_type: str): self.execute() return self + def register_trigger(self, account): + """ + Creates a JSON file for the register trigger and executes it using the Iroha CLI. + + :param account: The account to be used in the register_trigger. + :type account: str + """ + + json_template_path = ( + Path(BASE_DIR)/'pytests'/'common'/'json_isi_examples'/'register_trigger.json') + trigger_data = read_isi_from_json(str(json_template_path)) + trigger_data[0]["Register"]["Trigger"]["action"]["authority"] = str(account) + + json_temp_file_path = Path(ROOT_DIR) / 'isi_register_trigger.json' + write_isi_to_json(trigger_data, str(json_temp_file_path)) + + self._execute_pipe( + ['cat', str(json_temp_file_path)], + [self.BASE_PATH] + self.BASE_FLAGS + ['json']) + + return self + + def unregister_asset(self, asset_id): + """ + Creates a JSON file for the unregister asset and executes it using the Iroha CLI. + + :param asset_id: The object ID to be used in the unregister_asset. + :type asset_id: str + """ + + json_template_path = ( + Path(BASE_DIR) /'pytests'/'common'/'json_isi_examples'/'unregister_asset.json') + asset_data = read_isi_from_json(str(json_template_path)) + asset_data[0]["Unregister"]["Asset"]["object_id"] = str(asset_id) + + json_temp_file_path = Path(ROOT_DIR) / 'isi_unregister_asset.json' + write_isi_to_json(asset_data, str(json_temp_file_path)) + + self._execute_pipe( + ['cat', str(json_temp_file_path)], + [self.BASE_PATH] + self.BASE_FLAGS + ['json']) + + return self + + def should(self, _expected): """ Placeholder method for implementing assertions. @@ -257,34 +305,45 @@ def execute(self, command=None): if command is None: command = self.command else: - command = [self.BASE_PATH] + self.BASE_FLAGS + command.split() - allure_command = ' '.join(map(str, command[3:])) - print(allure_command) - with allure.step(f'{allure_command} on the {str(self.config.torii_api_port)} peer'): - try: - with subprocess.Popen( - command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True - ) as process: - self.stdout, self.stderr = process.communicate() - allure.attach( - self.stdout, - name='stdout', - attachment_type=allure.attachment_type.TEXT) - allure.attach( - self.stderr, - name='stderr', - attachment_type=allure.attachment_type.TEXT) - except Exception as exception: - raise RuntimeError( - f"Error executing command: {command}. " - f"Error: {exception}" - ) from exception - finally: - self.command = [self.BASE_PATH] + self.BASE_FLAGS - return self + command = [self.BASE_PATH] + self.BASE_FLAGS + shlex.split(command) + + if '|' in command: + pipe_index = command.index('|') + self._execute_pipe(command[:pipe_index], command[pipe_index + 1:]) + else: + self._execute_single(command) + + self.command = [self.BASE_PATH] + self.BASE_FLAGS + return self + + def _execute_pipe(self, cmd1, cmd2): + """ + Executes two commands connected by a pipe. + """ + with (subprocess.Popen( + cmd1, stdout=subprocess.PIPE) as proc1, + subprocess.Popen( + cmd2, stdin=proc1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc2): + self.stdout, self.stderr = proc2.communicate() + self.transaction_hash = extract_hash(self.stdout) + self._attach_allure_reports() + + def _execute_single(self, command): + """ + Executes a single command. + """ + with subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) as process: + self.stdout, self.stderr = process.communicate() + self.transaction_hash = extract_hash(self.stdout) + self._attach_allure_reports() + + def _attach_allure_reports(self): + """ + Attaches stdout and stderr to Allure reports. + """ + allure.attach(self.stdout, name='stdout', attachment_type=allure.attachment_type.TEXT) + allure.attach(self.stderr, name='stderr', attachment_type=allure.attachment_type.TEXT) @property def config(self) -> Config: diff --git a/client_cli/pytests/src/client_cli/configuration.py b/client_cli/pytests/src/client_cli/configuration.py index 2f69e4edc57..d581377b830 100644 --- a/client_cli/pytests/src/client_cli/configuration.py +++ b/client_cli/pytests/src/client_cli/configuration.py @@ -1,17 +1,17 @@ """ This module provides a Config class to manage Iroha network configuration. """ - +import glob import json import os import random -from urllib.parse import urlparse class Config: """ - Configuration class to handle Iroha network configuration. The class provides methods for loading - the configuration from a file, updating the TORII_API_URL with a random port number from the specified + Configuration class to handle Iroha network configuration. + The class provides methods for loading the configuration from a file, + updating the TORII_API_URL with a random port number from the specified range, and accessing the configuration values. :param port_min: The minimum port number for the TORII_API_URL. @@ -39,20 +39,42 @@ def load(self, path_config_client_cli): self._config = json.load(config_file) self.file = path_config_client_cli - def update_torii_api_port(self): + def generate_by_peers(self, peers_configs_dir): + """ + Generate configuration files for each port in the range from port_min to port_max. """ - Update the TORII_API_URL configuration value - with a random port number from the specified range. + if self._config is None: + raise ValueError( + "No configuration loaded. Use load() method to load the configuration.") + + if self.port_min >= self.port_max: + raise ValueError("port_min must be less than port_max.") + + os.makedirs(peers_configs_dir, exist_ok=True) + + for port in range(self.port_min, self.port_max + 1): + config_copy = self._config.copy() + config_copy['TORII_API_URL'] = f"http://localhost:{port}" + file_name = f"config_to_peer_{port}.json" + file_path = os.path.join(peers_configs_dir, file_name) + with open(file_path, 'w', encoding='utf-8') as config_file: + json.dump(config_copy, config_file, indent=4) + + def select_random_peer_config(self): + """ + Select and load a random configuration file generated by the generate_by_peers method. + This updates the current configuration to the one chosen. :return: None """ - if self._config is None: - raise ValueError("No configuration loaded. Use load_config(path_config_client_cli) to load the configuration.") - parsed_url = urlparse(self._config['TORII_API_URL']) - new_netloc = parsed_url.hostname + ':' + str(random.randint(self.port_min, self.port_max)) - self._config['TORII_API_URL'] = parsed_url._replace(netloc=new_netloc).geturl() - with open(self.file, 'w', encoding='utf-8') as config_file: - json.dump(self._config, config_file) + peers_configs = glob.glob('path/to/peers/configs/*.json') + if not peers_configs: + raise ValueError( + "Peer configuration files not found. First generate them using generate_by_peers.") + + chosen_config_file = random.choice(peers_configs) + + self.load(chosen_config_file) @property def torii_api_port(self): @@ -62,7 +84,7 @@ def torii_api_port(self): :return: The updated TORII_API_URL. :rtype: str """ - self.update_torii_api_port() + self.select_random_peer_config() return self._config['TORII_API_URL'] @property diff --git a/client_cli/pytests/src/client_cli/have.py b/client_cli/pytests/src/client_cli/have.py index 3bb51878891..9bd87b1f314 100644 --- a/client_cli/pytests/src/client_cli/have.py +++ b/client_cli/pytests/src/client_cli/have.py @@ -3,12 +3,20 @@ """ import json + import allure from src.client_cli import client_cli, iroha, match def expected_in_actual(expected, actual) -> bool: + """ + Check if the expected result is present in the actual result. + + :param expected: The expected result. + :param actual: The actual result. + :return: True if expected is in actual, False otherwise. + """ allure.attach( json.dumps(actual), name='actual', @@ -28,7 +36,7 @@ def domain(expected, owned_by=None): :param expected: The expected domain object. :param owned_by: The owner of the domain, default is None. - :return: True if the domain is present (and owned by the specified owner if provided), False otherwise. + :return: True if the domain is present and owned by the specified owner if provided. """ def domain_in_domains() -> bool: @@ -70,7 +78,9 @@ def asset_definition(expected): expected_domain = expected.split('#')[1] def asset_definition_in_asset_definitions() -> bool: - asset_definitions = iroha.list_filter(f'{{"Identifiable": {{"Is": "{expected_domain}"}}}}').asset_definitions() + asset_definitions = ( + iroha.list_filter( + f'{{"Identifiable": {{"Is": "{expected_domain}"}}}}').asset_definitions()) return expected_in_actual(expected, asset_definitions) return client_cli.wait_for(asset_definition_in_asset_definitions) @@ -100,15 +110,15 @@ def asset_has_quantity(expected_asset_id, expected_quantity): """ def check_quantity() -> bool: - assets = iroha.list_filter(f'{{"Identifiable": {{"Is": "{expected_asset_id}"}}}}').assets() + assets = iroha.list_filter( + f'{{"Identifiable": {{"Is": "{expected_asset_id}"}}}}').assets() actual_quantity = None - for asset in assets: - if asset == expected_asset_id: + for asset_item in assets: + if asset_item == expected_asset_id: actual_quantity = assets.get(expected_asset_id, {})["value"]["Quantity"] break - if actual_quantity is None: - raise Exception(f"Asset with ID {expected_asset_id} not found.") + raise ValueError(f"Asset with ID {expected_asset_id} not found.") allure.attach( json.dumps(actual_quantity), diff --git a/client_cli/pytests/src/client_cli/iroha.py b/client_cli/pytests/src/client_cli/iroha.py index 38174fefeac..1e0ec2f7164 100644 --- a/client_cli/pytests/src/client_cli/iroha.py +++ b/client_cli/pytests/src/client_cli/iroha.py @@ -4,7 +4,8 @@ import json from typing import Dict, List -from src.client_cli.client_cli import ClientCli, Config + +from src.client_cli.client_cli import ClientCli class Iroha(ClientCli): @@ -13,14 +14,6 @@ class Iroha(ClientCli): for interacting with the Iroha network. """ - def __init__(self, config: Config): - """ - :param config: A configuration object containing the details for the client. - :type config: Config - :param path: The path where the client executable is located. - :type path: str - """ - super().__init__(config) def _execute_command(self, command_name: str): """ @@ -32,17 +25,29 @@ def _execute_command(self, command_name: str): self.command.insert(3, command_name) self.execute() - def should(self, _expected): + def should(self, *args, **kwargs): """ Placeholder method for implementing assertions. - :param expected: The expected value. - :type expected: str + :param kwargs: :return: The current Iroha object. :rtype: Iroha """ return self + def should_not(self, func): + """ + Decorator that inverts the result of the check function. + + :param func: The function to be inverted. + :return: Inverted result of the function. + """ + + def wrapper(*args, **kwargs): + return not func(*args, **kwargs) + + return wrapper + def domains(self) -> Dict[str, Dict]: """ Retrieve domains from the Iroha network and return then as list of ids. diff --git a/client_cli/pytests/src/client_cli/match.py b/client_cli/pytests/src/client_cli/match.py index 4aa9b65cadf..8eb122942bc 100644 --- a/client_cli/pytests/src/client_cli/match.py +++ b/client_cli/pytests/src/client_cli/match.py @@ -4,6 +4,7 @@ import allure + def client_cli_have_error(expected: str, actual: str): """ Checks if the command-line client has the expected error. diff --git a/client_cli/pytests/test/__init__.py b/client_cli/pytests/test/__init__.py index 1eebe6afb9f..c26a3db8577 100644 --- a/client_cli/pytests/test/__init__.py +++ b/client_cli/pytests/test/__init__.py @@ -2,24 +2,18 @@ This module provides access to fixtures for testing. """ from .conftest import ( - GIVEN_127_lenght_name, - GIVEN_128_lenght_name, - GIVEN_129_lenght_name, - GIVEN_new_one_existing_account, - GIVEN_existing_asset_definition_with_quantity_value_type, - GIVEN_existing_asset_definition_with_store_value_type, - GIVEN_existing_domain_with_uppercase_letter, - GIVEN_new_one_existing_domain, - GIVEN_fake_asset_name, - GIVEN_fake_name, - GIVEN_key_with_invalid_character_in_key, - GIVEN_not_existing_name, - GIVEN_public_key, - GIVEN_quantity_value, - GIVEN_random_character, - before_each, - GIVEN_string_with_reserved_character, - GIVEN_string_with_whitespaces, - GIVEN_quantity_value_type, - GIVEN_currently_authorized_account, - GIVEN_currently_account_quantity_with_two_quantity_of_asset) + GIVEN_127_lenght_name, GIVEN_128_lenght_name, GIVEN_129_lenght_name, + GIVEN_big_quantity_value_type, + GIVEN_currently_account_quantity_with_two_quantity_of_asset, + GIVEN_currently_authorized_account, GIVEN_fake_asset_name, GIVEN_fake_name, + GIVEN_key_with_invalid_character_in_key, GIVEN_minted_asset_quantity, + GIVEN_not_existing_name, GIVEN_public_key, + GIVEN_quantity_asset_for_account, GIVEN_quantity_value, + GIVEN_quantity_value_type, GIVEN_random_character, + GIVEN_registered_account, + GIVEN_registered_asset_definition_with_big_quantity_value_type, + GIVEN_registered_asset_definition_with_quantity_value_type, + GIVEN_registered_asset_definition_with_store_value_type, + GIVEN_registered_domain, GIVEN_registered_domain_with_uppercase_letter, + GIVEN_store_value_type, GIVEN_string_with_reserved_character, + GIVEN_string_with_whitespaces, before_all, before_each) diff --git a/client_cli/pytests/test/accounts/conftest.py b/client_cli/pytests/test/accounts/conftest.py index b925774b068..f745f3b07be 100644 --- a/client_cli/pytests/test/accounts/conftest.py +++ b/client_cli/pytests/test/accounts/conftest.py @@ -1,17 +1,12 @@ -import pytest +from test import (GIVEN_127_lenght_name, GIVEN_129_lenght_name, + GIVEN_fake_name, GIVEN_key_with_invalid_character_in_key, + GIVEN_not_existing_name, GIVEN_public_key, + GIVEN_random_character, GIVEN_registered_account, + GIVEN_registered_domain, before_all, before_each) + import allure +import pytest -from test import ( - GIVEN_127_lenght_name, - GIVEN_129_lenght_name, - GIVEN_new_one_existing_account, - GIVEN_new_one_existing_domain, - GIVEN_fake_name, - GIVEN_key_with_invalid_character_in_key, - GIVEN_not_existing_name, - GIVEN_public_key, - GIVEN_random_character, - before_each) @pytest.fixture(scope="function", autouse=True) def account_test_setup(): diff --git a/client_cli/pytests/test/accounts/test_accounts_query_filters.py b/client_cli/pytests/test/accounts/test_accounts_query_filters.py index cd76a8a18da..4e443196337 100644 --- a/client_cli/pytests/test/accounts/test_accounts_query_filters.py +++ b/client_cli/pytests/test/accounts/test_accounts_query_filters.py @@ -1,12 +1,14 @@ import json + import allure -from src.client_cli import iroha, client_cli +from src.client_cli import client_cli, iroha + # using existing account to have at least one account in response -def test_filter_by_domain(GIVEN_new_one_existing_account): +def test_filter_by_domain(GIVEN_registered_account): def condition(): - domain = GIVEN_new_one_existing_account.domain + domain = GIVEN_registered_account.domain with allure.step( f'WHEN client_cli query accounts ' f'in the "{domain}" domain'): @@ -20,9 +22,9 @@ def condition(): return accounts and all(account.endswith(domain) for account in accounts) client_cli.wait_for(condition) -def test_filter_by_account_name(GIVEN_new_one_existing_account): +def test_filter_by_account_name(GIVEN_registered_account): def condition(): - name = GIVEN_new_one_existing_account.name + name = GIVEN_registered_account.name with allure.step( f'WHEN client_cli query accounts with name "{name}"'): accounts = iroha.list_filter(f'{{"Identifiable": {{"StartsWith": "{name}@"}}}}').accounts() @@ -35,9 +37,9 @@ def condition(): return accounts and all(account.startswith(name) for account in accounts) client_cli.wait_for(condition) -def test_filter_by_account_id(GIVEN_new_one_existing_account): +def test_filter_by_account_id(GIVEN_registered_account): def condition(): - account_id = GIVEN_new_one_existing_account.name + "@" + GIVEN_new_one_existing_account.domain + account_id = GIVEN_registered_account.name + "@" + GIVEN_registered_account.domain with allure.step( f'WHEN client_cli query accounts with account id "{account_id}"'): accounts = iroha.list_filter(f'{{"Identifiable": {{"Is": "{account_id}"}}}}').accounts() diff --git a/client_cli/pytests/test/accounts/test_register_accounts.py b/client_cli/pytests/test/accounts/test_register_accounts.py index c2954337bee..467ff0c614c 100644 --- a/client_cli/pytests/test/accounts/test_register_accounts.py +++ b/client_cli/pytests/test/accounts/test_register_accounts.py @@ -4,6 +4,7 @@ from common.consts import Stderr from src.client_cli import client_cli, have, iroha + @pytest.fixture(scope="function", autouse=True) def story_account_register_account(): allure.dynamic.story('Account registers an account') @@ -12,16 +13,16 @@ def story_account_register_account(): @allure.label('sdk_test_id', 'register_account') def test_register_account( GIVEN_fake_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key): with allure.step( f'WHEN client_cli registers the account "{GIVEN_fake_name}" ' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): + f'in the "{GIVEN_registered_domain.name}" domain'): client_cli.register().account( account=GIVEN_fake_name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, key=GIVEN_public_key) - registered = GIVEN_fake_name + '@' + GIVEN_new_one_existing_domain.name + registered = GIVEN_fake_name + '@' + GIVEN_registered_domain.name with allure.step( f'THEN Iroha should have the "{registered}" account'): iroha.should(have.account(registered)) @@ -31,19 +32,19 @@ def test_register_account( @pytest.mark.xfail(reason="TO DO") def test_register_account_with_two_public_keys( GIVEN_fake_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key): assert 0 @allure.label('sdk_test_id', 'register_account_with_empty_name') def test_register_account_with_empty_name( - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key): with allure.step( f'WHEN client_cli tries to register an account with an empty name ' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): - client_cli.register().account(account='', domain=GIVEN_new_one_existing_domain.name, key=GIVEN_public_key) + f'in the "{GIVEN_registered_domain.name}" domain'): + client_cli.register().account(account='', domain=GIVEN_registered_domain.name, key=GIVEN_public_key) with allure.step( f'THEN сlient_cli should have the account error: "{Stderr.CANNOT_BE_EMPTY}"'): client_cli.should(have.error(Stderr.CANNOT_BE_EMPTY.value)) @@ -52,17 +53,17 @@ def test_register_account_with_empty_name( @allure.label('sdk_test_id', 'register_account_with_existing_name') def test_register_account_with_existing_name( - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key, - GIVEN_new_one_existing_account): + GIVEN_registered_account): with allure.step( f'WHEN client_cli tries to register an account ' - f'with the same name "{GIVEN_new_one_existing_domain.name}" ' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): - client_cli.register().account(account=GIVEN_new_one_existing_account.name, domain=GIVEN_new_one_existing_account.domain, - key=GIVEN_new_one_existing_account.public_key) + f'with the same name "{GIVEN_registered_domain.name}" ' + f'in the "{GIVEN_registered_domain.name}" domain'): + client_cli.register().account(account=GIVEN_registered_account.name, domain=GIVEN_registered_account.domain, + key=GIVEN_registered_account.public_key) with allure.step( - f'THEN client_cli should have the account error: "{GIVEN_new_one_existing_domain.name}"'): + f'THEN client_cli should have the account error: "{GIVEN_registered_domain.name}"'): client_cli.should(have.error(Stderr.REPETITION.value)) @@ -84,11 +85,11 @@ def test_register_account_with_invalid_domain( @allure.label('sdk_test_id', 'register_account_with_invalid_character_in_key') def test_register_account_with_invalid_character_in_key( GIVEN_fake_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_key_with_invalid_character_in_key): with allure.step( 'WHEN client_cli tries to register an account with invalid character in the key'): - client_cli.register().account(account=GIVEN_fake_name, domain=GIVEN_new_one_existing_domain.name, + client_cli.register().account(account=GIVEN_fake_name, domain=GIVEN_registered_domain.name, key=GIVEN_key_with_invalid_character_in_key) with allure.step( 'THEN client_cli should have the error'): @@ -98,13 +99,13 @@ def test_register_account_with_invalid_character_in_key( @allure.label('sdk_test_id', 'register_account_with_max_name') def test_register_account_with_max_name( GIVEN_127_lenght_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key): with allure.step( 'WHEN client_cli register an account with the 127 lenght name'): - client_cli.register().account(account=GIVEN_127_lenght_name, domain=GIVEN_new_one_existing_domain.name, + client_cli.register().account(account=GIVEN_127_lenght_name, domain=GIVEN_registered_domain.name, key=GIVEN_public_key) - registered = GIVEN_127_lenght_name + '@' + GIVEN_new_one_existing_domain.name + registered = GIVEN_127_lenght_name + '@' + GIVEN_registered_domain.name with allure.step( f'THEN Iroha should have the "{registered}" account'): iroha.should(have.account(registered)) @@ -114,19 +115,19 @@ def test_register_account_with_max_name( @allure.label('sdk_test_id', 'register_account_with_special_characters') @pytest.mark.xfail(reason="TO DO") def test_register_account_with_special_characters( - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key): assert 0 @allure.label('sdk_test_id', 'register_account_with_long_account_name') def test_register_account_with_long_account_name( - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_129_lenght_name, GIVEN_public_key): with allure.step( 'WHEN client_cli tries to register an account with a name with 129 characters'): - client_cli.register().account(account=GIVEN_129_lenght_name, domain=GIVEN_new_one_existing_domain.name, + client_cli.register().account(account=GIVEN_129_lenght_name, domain=GIVEN_registered_domain.name, key=GIVEN_public_key) with allure.step( f'THEN client_cli should have the name error: "{Stderr.TOO_LONG}"'): @@ -136,6 +137,6 @@ def test_register_account_with_long_account_name( @pytest.mark.xfail(reason="TO DO") def test_register_account_with_metadata( GIVEN_fake_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_public_key): assert 0 diff --git a/client_cli/pytests/test/accounts/test_set_key_value_pair.py b/client_cli/pytests/test/accounts/test_set_key_value_pair.py index 406bf9726b9..96a1021bdc1 100644 --- a/client_cli/pytests/test/accounts/test_set_key_value_pair.py +++ b/client_cli/pytests/test/accounts/test_set_key_value_pair.py @@ -1,6 +1,7 @@ import allure import pytest + @pytest.fixture(scope="function", autouse=True) def story_client_change_account_metadata(): allure.dynamic.story("Account set key value pair") @@ -9,14 +10,14 @@ def story_client_change_account_metadata(): @pytest.mark.xfail(reason="TO DO") def test_set_key_value_in_foreign_asset_after_granting_role( GIVEN_currently_authorized_account, - GIVEN_new_one_existing_account, - GIVEN_existing_asset_definition_with_store_value_type): + GIVEN_registered_account, + GIVEN_registered_asset_definition_with_store_value_type): assert 0 @allure.label('sdk_test_id', 'set_key_value_pair_for_another_account_asset_definition') @pytest.mark.xfail(reason="TO DO") def test_set_key_value_pair_for_another_account_asset_definition( GIVEN_currently_authorized_account, - GIVEN_new_one_existing_account, - GIVEN_existing_asset_definition_with_store_value_type): + GIVEN_registered_account, + GIVEN_registered_asset_definition_with_store_value_type): assert 0 diff --git a/client_cli/pytests/test/assets/conftest.py b/client_cli/pytests/test/assets/conftest.py index 1e71664f7c4..02ec6a257d6 100644 --- a/client_cli/pytests/test/assets/conftest.py +++ b/client_cli/pytests/test/assets/conftest.py @@ -1,19 +1,18 @@ -import pytest -import allure - from test import ( - GIVEN_new_one_existing_account, - GIVEN_existing_asset_definition_with_quantity_value_type, - GIVEN_existing_asset_definition_with_store_value_type, - GIVEN_new_one_existing_domain, - GIVEN_fake_asset_name, - GIVEN_fake_name, - GIVEN_public_key, - GIVEN_quantity_value, - GIVEN_quantity_value_type, - GIVEN_currently_authorized_account, + GIVEN_129_lenght_name, GIVEN_big_quantity_value_type, GIVEN_currently_account_quantity_with_two_quantity_of_asset, - before_each) + GIVEN_currently_authorized_account, GIVEN_fake_asset_name, GIVEN_fake_name, + GIVEN_minted_asset_quantity, GIVEN_not_existing_name, GIVEN_public_key, + GIVEN_quantity_asset_for_account, GIVEN_quantity_value, + GIVEN_quantity_value_type, GIVEN_registered_account, + GIVEN_registered_asset_definition_with_big_quantity_value_type, + GIVEN_registered_asset_definition_with_quantity_value_type, + GIVEN_registered_asset_definition_with_store_value_type, + GIVEN_registered_domain, GIVEN_store_value_type, before_all, before_each) + +import allure +import pytest + @pytest.fixture(scope="function", autouse=True) def asset_test_setup(): diff --git a/client_cli/pytests/test/assets/test_assets_query_filters.py b/client_cli/pytests/test/assets/test_assets_query_filters.py index 789f27d2f1f..3e58a547e8e 100644 --- a/client_cli/pytests/test/assets/test_assets_query_filters.py +++ b/client_cli/pytests/test/assets/test_assets_query_filters.py @@ -1,7 +1,9 @@ import json + import allure -from src.client_cli import iroha, client_cli +from src.client_cli import client_cli, iroha + # using existing account with asset to have at least one in response def test_filter_by_domain(GIVEN_currently_account_quantity_with_two_quantity_of_asset): diff --git a/client_cli/pytests/test/assets/test_burn_assets.py b/client_cli/pytests/test/assets/test_burn_assets.py index 4c53db92ac6..80f69f18052 100644 --- a/client_cli/pytests/test/assets/test_burn_assets.py +++ b/client_cli/pytests/test/assets/test_burn_assets.py @@ -30,8 +30,8 @@ def test_burn_asset_for_account_in_same_domain( @allure.label('permission', 'can_burn_assets_with_definition') @pytest.mark.xfail(reason="TO DO") def test_burn_other_user_asset( - GIVEN_existing_asset_definition_with_quantity_value_type, - GIVEN_new_one_existing_account, + GIVEN_registered_asset_definition_with_quantity_value_type, + GIVEN_registered_account, GIVEN_quantity_value): assert 0 @@ -51,5 +51,5 @@ def test_not_burn_asset_if_condition_not_met( @allure.label("sdk_test_id", "burn_fixed_asset") @pytest.mark.xfail(reason="TO DO") def test_burn_fixed_asset( - GIVEN_new_one_existing_account): + GIVEN_registered_account): assert 0 diff --git a/client_cli/pytests/test/assets/test_mint_assets.py b/client_cli/pytests/test/assets/test_mint_assets.py index 198ddac3ca2..1ea0d8246a5 100644 --- a/client_cli/pytests/test/assets/test_mint_assets.py +++ b/client_cli/pytests/test/assets/test_mint_assets.py @@ -10,27 +10,63 @@ def story_account_mint_asset(): @allure.label('sdk_test_id', 'mint_asset_for_account_in_same_domain') def test_mint_asset_for_account_in_same_domain( - GIVEN_existing_asset_definition_with_quantity_value_type, - GIVEN_new_one_existing_account, + GIVEN_registered_asset_definition_with_quantity_value_type, + GIVEN_registered_account, GIVEN_quantity_value): with allure.step( - f'WHEN client_cli mint the asset "{GIVEN_existing_asset_definition_with_quantity_value_type.name}" ' - f'for the "{GIVEN_new_one_existing_account.name}" ' - f'in the "{GIVEN_existing_asset_definition_with_quantity_value_type.domain}" domain' + f'WHEN client_cli mint the asset "{GIVEN_registered_asset_definition_with_quantity_value_type.name}" ' + f'for the "{GIVEN_registered_account.name}" ' + f'in the "{GIVEN_registered_asset_definition_with_quantity_value_type.domain}" domain' ): client_cli.mint().asset( - account=GIVEN_new_one_existing_account, - asset_definition=GIVEN_existing_asset_definition_with_quantity_value_type, + account=GIVEN_registered_account, + asset_definition=GIVEN_registered_asset_definition_with_quantity_value_type, value_of_value_type=GIVEN_quantity_value ) with allure.step( - f'THEN "{GIVEN_new_one_existing_account}" account ' - f'should have the "{GIVEN_existing_asset_definition_with_quantity_value_type}" asset definition'): - iroha.should(have.asset(f'{GIVEN_existing_asset_definition_with_quantity_value_type.name}##{GIVEN_new_one_existing_account}')) + f'THEN "{GIVEN_registered_account}" account ' + f'should have the "{GIVEN_registered_asset_definition_with_quantity_value_type}" asset definition'): + iroha.should(have.asset(f'{GIVEN_registered_asset_definition_with_quantity_value_type.name}##{GIVEN_registered_account}')) + iroha.should(have.asset_has_quantity( + f'{GIVEN_registered_asset_definition_with_quantity_value_type.name}##{GIVEN_registered_account}', + GIVEN_quantity_value)) +@allure.label('sdk_test_id', 'mint_asset_quantity_after_minting') +def test_mint_asset_quantity_after_minting( + GIVEN_minted_asset_quantity): + with allure.step( + f'WHEN client_cli mint additional asset "{GIVEN_minted_asset_quantity.definition}" ' + f'for the "{GIVEN_minted_asset_quantity.account}" ' + f'with "{GIVEN_minted_asset_quantity.value}" quantity' + ): + client_cli.mint().asset( + account=GIVEN_minted_asset_quantity.account, + asset_definition=GIVEN_minted_asset_quantity.definition, + value_of_value_type="1" + ) + expected_quantity = int(GIVEN_minted_asset_quantity.value) + 1 + with allure.step( + f'THEN "{GIVEN_minted_asset_quantity.account}" account ' + f'should have the "{expected_quantity}" asset definition ' + f'with updated quantity'): + iroha.should(have.asset_has_quantity( + f'{GIVEN_minted_asset_quantity.definition.name}##{GIVEN_minted_asset_quantity.account}', + str(expected_quantity))) + +@allure.label("sdk_test_id", "mint_big_quantity_asset") +@pytest.mark.xfail(reason="https://github.com/hyperledger/iroha/issues/4035") +def test_mint_big_quantity_asset( + GIVEN_registered_asset_definition_with_big_quantity_value_type): + assert 0 @allure.label("sdk_test_id", "mint_fixed_asset") -@pytest.mark.xfail(reason="TO DO") +@pytest.mark.xfail(reason="https://github.com/hyperledger/iroha/issues/4035") def test_mint_fixed_asset( - GIVEN_new_one_existing_account): + GIVEN_registered_account): + assert 0 + +@allure.label("sdk_test_id", "mint_store_asset") +@pytest.mark.xfail(reason="https://github.com/hyperledger/iroha/issues/4035") +def test_mint_store_asset( + GIVEN_registered_account): assert 0 diff --git a/client_cli/pytests/test/assets/test_register_asset_definitions.py b/client_cli/pytests/test/assets/test_register_asset_definitions.py index fcd5510750f..218325437d5 100644 --- a/client_cli/pytests/test/assets/test_register_asset_definitions.py +++ b/client_cli/pytests/test/assets/test_register_asset_definitions.py @@ -4,6 +4,7 @@ from common.consts import Stderr from src.client_cli import client_cli, have, iroha + @pytest.fixture(scope="function", autouse=True) def story_account_registers_asset_definitions(): allure.dynamic.story('Account registers an asset definition') @@ -13,42 +14,75 @@ def story_account_registers_asset_definitions(): @allure.label('sdk_test_id', 'register_asset_definition_with_quantity_value_type') def test_register_asset_definition_with_quantity_value_type( GIVEN_fake_asset_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_quantity_value_type): with allure.step( f'WHEN client_cli registers the asset_definition "{GIVEN_fake_asset_name}" ' f'with "{GIVEN_quantity_value_type}" value type' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): + f'in the "{GIVEN_registered_domain.name}" domain'): client_cli.register().asset().definition( asset=GIVEN_fake_asset_name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, value_type=GIVEN_quantity_value_type) with allure.step( f'THEN Iroha should have the asset "{GIVEN_fake_asset_name}"'): - iroha.should(have.asset_definition(GIVEN_fake_asset_name + '#' + GIVEN_new_one_existing_domain.name)) + iroha.should(have.asset_definition(GIVEN_fake_asset_name + '#' + GIVEN_registered_domain.name)) +@allure.label('sdk_test_id', 'register_asset_definition_with_too_long_name') +def test_register_asset_definition_with_too_long_name( + GIVEN_129_lenght_name, + GIVEN_registered_domain, + GIVEN_quantity_value_type): + with allure.step( + f'WHEN client_cli registers the asset_definition "{GIVEN_129_lenght_name}" ' + f'with "{GIVEN_quantity_value_type}" value type' + f'in the "{GIVEN_registered_domain.name}" domain'): + client_cli.register().asset().definition( + asset=GIVEN_129_lenght_name, + domain=GIVEN_registered_domain.name, + value_type=GIVEN_quantity_value_type) + with allure.step( + f'THEN Iroha should have the asset "{GIVEN_129_lenght_name}"'): + client_cli.should(have.error(Stderr.TOO_LONG.value)) @allure.label('sdk_test_id', 'register_asset_definition_with_store_value_type') def test_register_asset_definition_with_store_value_type( GIVEN_fake_asset_name, - GIVEN_new_one_existing_domain, + GIVEN_registered_domain, GIVEN_store_value_type): with allure.step( f'WHEN client_cli registers the asset_definition "{GIVEN_fake_asset_name}" ' f'with "{GIVEN_store_value_type}" value type' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): + f'in the "{GIVEN_registered_domain.name}" domain'): client_cli.register().asset().definition( asset=GIVEN_fake_asset_name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, value_type=GIVEN_store_value_type) with allure.step( f'THEN Iroha should have the asset "{GIVEN_fake_asset_name}"'): - iroha.should(have.asset_definition(GIVEN_fake_asset_name + '#' + GIVEN_new_one_existing_domain.name)) + iroha.should(have.asset_definition(GIVEN_fake_asset_name + '#' + GIVEN_registered_domain.name)) + +@allure.label('sdk_test_id', 'register_asset_definition_with_big_quantity_type') +def test_register_asset_definition_with_big_quantity_type( + GIVEN_fake_asset_name, + GIVEN_registered_domain, + GIVEN_big_quantity_value_type): + with allure.step( + f'WHEN client_cli registers the asset_definition "{GIVEN_fake_asset_name}" ' + f'with "{GIVEN_big_quantity_value_type}" value type' + f'in the "{GIVEN_registered_domain.name}" domain'): + client_cli.register().asset().definition( + asset=GIVEN_fake_asset_name, + domain=GIVEN_registered_domain.name, + value_type=GIVEN_big_quantity_value_type) + with allure.step( + f'THEN Iroha should have the asset "{GIVEN_fake_asset_name}"'): + iroha.should(have.asset_definition(GIVEN_fake_asset_name + '#' + GIVEN_registered_domain.name)) @allure.label("sdk_test_id", "register_asset_definition_with_metadata") @pytest.mark.xfail(reason="TO DO") def test_register_asset_definition_with_metadata( GIVEN_fake_asset_name, - GIVEN_new_one_existing_domain): + GIVEN_registered_domain): assert 0 @@ -56,32 +90,32 @@ def test_register_asset_definition_with_metadata( @pytest.mark.xfail(reason="TO DO") def test_register_fixed_asset_definition( GIVEN_fake_asset_name, - GIVEN_new_one_existing_domain): + GIVEN_registered_domain): assert 0 @allure.label('sdk_test_id', 'register_asset_with_existing_name') def test_register_asset_with_existing_name( - GIVEN_existing_asset_definition_with_quantity_value_type): + GIVEN_registered_asset_definition_with_quantity_value_type): with allure.step( - f'WHEN client_cli tries to register an asset definition with the same name "{GIVEN_existing_asset_definition_with_quantity_value_type.name}"' - f'in the "{GIVEN_existing_asset_definition_with_quantity_value_type.domain}" domain'): - client_cli.register().asset().definition(asset=GIVEN_existing_asset_definition_with_quantity_value_type.name, - domain=GIVEN_existing_asset_definition_with_quantity_value_type.domain, - value_type=GIVEN_existing_asset_definition_with_quantity_value_type.value_type) + f'WHEN client_cli tries to register an asset definition with the same name "{GIVEN_registered_asset_definition_with_quantity_value_type.name}"' + f'in the "{GIVEN_registered_asset_definition_with_quantity_value_type.domain}" domain'): + client_cli.register().asset().definition(asset=GIVEN_registered_asset_definition_with_quantity_value_type.name, + domain=GIVEN_registered_asset_definition_with_quantity_value_type.domain, + value_type=GIVEN_registered_asset_definition_with_quantity_value_type.value_type) with allure.step( - f'THEN client_cli should have the asset definition error: "{GIVEN_existing_asset_definition_with_quantity_value_type.__repr__()}"'): + f'THEN client_cli should have the asset definition error: "{GIVEN_registered_asset_definition_with_quantity_value_type.__repr__()}"'): client_cli.should(have.error(Stderr.REPETITION.value)) @allure.label('sdk_test_id', 'register_asset_with_empty_name') def test_register_asset_with_empty_name( - GIVEN_new_one_existing_domain): + GIVEN_registered_domain): with allure.step( f'WHEN client_cli tries to register an asset definition with an empty name' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): - client_cli.register().asset().definition(asset='', domain=GIVEN_new_one_existing_domain.name, value_type='Quantity') + f'in the "{GIVEN_registered_domain.name}" domain'): + client_cli.register().asset().definition(asset='', domain=GIVEN_registered_domain.name, value_type='Quantity') with allure.step( f'THEN сlient_cli should have the asset error: "{Stderr.CANNOT_BE_EMPTY}"'): client_cli.should(have.error(Stderr.CANNOT_BE_EMPTY.value)) @@ -106,11 +140,11 @@ def test_register_asset_with_not_existing_domain( @allure.label('sdk_test_id', 'register_asset_with_too_long_value_type') def test_register_asset_with_too_long_value_type( GIVEN_fake_asset_name, - GIVEN_new_one_existing_domain): + GIVEN_registered_domain): with allure.step( 'WHEN client_cli tries to register an asset definition with too long value type'): client_cli.register().asset().definition(asset=GIVEN_fake_asset_name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, value_type='coin') with allure.step( 'THEN client_cli should have the error'): diff --git a/client_cli/pytests/test/assets/test_transfer_assets.py b/client_cli/pytests/test/assets/test_transfer_assets.py index 31601b5bbff..dfbbeb57b50 100644 --- a/client_cli/pytests/test/assets/test_transfer_assets.py +++ b/client_cli/pytests/test/assets/test_transfer_assets.py @@ -1,6 +1,7 @@ import allure import pytest +from common.consts import Stderr from src.client_cli import client_cli, have, iroha @@ -11,29 +12,73 @@ def story_account_transfer_asset(): @allure.label('sdk_test_id', 'transfer_asset') @allure.label('permission', 'no_permission_required') def test_transfer_asset( - GIVEN_new_one_existing_account, + GIVEN_registered_account, GIVEN_currently_authorized_account, GIVEN_currently_account_quantity_with_two_quantity_of_asset): with allure.step(f'WHEN {GIVEN_currently_authorized_account.name} transfers 1 Quantity' f'of {GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition.name}' - f'to {GIVEN_new_one_existing_account.name}'): + f'to {GIVEN_registered_account.name}'): client_cli.transfer( asset=GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition, source_account=GIVEN_currently_authorized_account, - target_account=GIVEN_new_one_existing_account, + target_account=GIVEN_registered_account, quantity="1") with allure.step(f'THEN {GIVEN_currently_authorized_account.name} has 1 Quantity ' f'of {GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition.name}' - f'AND {GIVEN_new_one_existing_account} has 1 more Quantity'): + f'AND {GIVEN_registered_account} has 1 more Quantity'): iroha.should(have.asset( - f'{GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition.name}#{GIVEN_currently_authorized_account.domain}#{GIVEN_new_one_existing_account}')) + f'{GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition.name}#{GIVEN_currently_authorized_account.domain}#{GIVEN_registered_account}')) +@allure.label('sdk_test_id', 'transfer_with_insufficient_funds') +@allure.label('permission', 'no_permission_required') +def test_transfer_with_insufficient_funds( + GIVEN_registered_account, + GIVEN_currently_authorized_account, + GIVEN_currently_account_quantity_with_two_quantity_of_asset): + with allure.step(f'WHEN {GIVEN_currently_authorized_account.name} attempts to transfer more than available Quantity' + f'of {GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition.name}' + f'to {GIVEN_registered_account.name}'): + client_cli.transfer( + asset=GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition, + source_account=GIVEN_currently_authorized_account, + target_account=GIVEN_registered_account, + quantity=str(int(GIVEN_currently_account_quantity_with_two_quantity_of_asset.value)+1)) + with allure.step(f'THEN {GIVEN_currently_authorized_account.name} still has the original Quantity ' + f'of {GIVEN_currently_account_quantity_with_two_quantity_of_asset.definition.name}' + f'AND {GIVEN_registered_account.name} does not receive any additional Quantity'): + client_cli.should(have.error(Stderr.INSUFFICIENT_FUNDS.value)) + +@allure.label('sdk_test_id', 'exchange_asset_intermediary') +@allure.label('permission', 'intermediary_permission_required') +@pytest.mark.xfail(reason="TO DO") +def test_exchange_asset_through_intermediary( + GIVEN_registered_account, + GIVEN_intermediary_with_transfer_permission, + GIVEN_seller_account_with_btc, + GIVEN_buyer_account_with_eth): + # with allure.step(f'WHEN {GIVEN_intermediary_with_transfer_permission.name}' + # f'exchanges BTC from {GIVEN_seller_account_with_btc.name}' + # f'with ETH from {GIVEN_buyer_account_with_eth.name}'): + # client_cli.exchange_assets( + # intermediary_account=GIVEN_intermediary_with_transfer_permission, + # seller_account=GIVEN_seller_account_with_btc, + # buyer_account=GIVEN_buyer_account_with_eth, + # btc_quantity="1", + # eth_quantity="10") + # + # with allure.step(f'THEN {GIVEN_seller_account_with_btc.name} receives ETH ' + # f'AND {GIVEN_buyer_account_with_eth.name} receives BTC'): + # iroha.should(have.asset( + # f'eth#{GIVEN_seller_account_with_btc.domain}', quantity="10")) + # iroha.should(have.asset( + # f'btc#{GIVEN_buyer_account_with_eth.domain}', quantity="1")) + assert 0 @allure.label('sdk_test_id', 'transfer_user_asset') @allure.label('permission', 'can_transfer_user_asset') @pytest.mark.xfail(reason="TO DO") def test_transfer_user_asset( - GIVEN_new_one_existing_account, + GIVEN_registered_account, GIVEN_currently_authorized_account): assert 0 diff --git a/client_cli/pytests/test/assets/test_unregister_asset.py b/client_cli/pytests/test/assets/test_unregister_asset.py new file mode 100644 index 00000000000..920a96c0665 --- /dev/null +++ b/client_cli/pytests/test/assets/test_unregister_asset.py @@ -0,0 +1,26 @@ +import allure +import pytest + +from src.client_cli import client_cli, have, iroha + + +@pytest.fixture(scope="function", autouse=True) +def story_account_unregisters_asset(): + allure.dynamic.story('Account unregisters an asset') + allure.dynamic.label('permission', 'no_permission_required') + + +@allure.label('sdk_test_id', 'unregister_asset') +@pytest.mark.parametrize("GIVEN_quantity_asset_for_account", ["alice@wonderland"], indirect=True) +@pytest.mark.xfail(reason="wait for #4039") +def test_unregister_asset( + GIVEN_quantity_asset_for_account, +): + with allure.step( + f'WHEN client_cli unregisters the asset "{GIVEN_quantity_asset_for_account.definition.name}"'): + client_cli.unregister_asset( + asset_id= f'{GIVEN_quantity_asset_for_account.definition.name}#{GIVEN_quantity_asset_for_account.account}@{GIVEN_quantity_asset_for_account.definition.domain}') + with allure.step( + f'THEN Iroha should not have the asset "{GIVEN_quantity_asset_for_account.definition.name}"'): + iroha.should(have.asset( + f'{GIVEN_quantity_asset_for_account.definition.name}##{GIVEN_quantity_asset_for_account.account}@{GIVEN_quantity_asset_for_account.definition.domain}')) diff --git a/client_cli/pytests/test/atomicity/conftest.py b/client_cli/pytests/test/atomicity/conftest.py index 5d06e5ef90e..79113e2abd5 100644 --- a/client_cli/pytests/test/atomicity/conftest.py +++ b/client_cli/pytests/test/atomicity/conftest.py @@ -1,8 +1,8 @@ -import pytest +from test import before_all, before_each + import allure +import pytest -from test import ( - before_each) @pytest.fixture(scope="function", autouse=True) def atomicity_test_setup(): diff --git a/client_cli/pytests/test/atomicity/test_multiple_instructions_within_transaction.py b/client_cli/pytests/test/atomicity/test_multiple_instructions_within_transaction.py index c05a70430ab..551cdcd7f0f 100644 --- a/client_cli/pytests/test/atomicity/test_multiple_instructions_within_transaction.py +++ b/client_cli/pytests/test/atomicity/test_multiple_instructions_within_transaction.py @@ -1,6 +1,7 @@ import allure import pytest + @pytest.fixture(scope="function", autouse=True) def story_client_sends_multiple_instructions_within_transaction(): allure.dynamic.story('Client sends a multiple instructions within transaction') diff --git a/client_cli/pytests/test/atomicity/test_pair_instructions_within_transaction.py b/client_cli/pytests/test/atomicity/test_pair_instructions_within_transaction.py index 679c7b0cfe1..5d650495211 100644 --- a/client_cli/pytests/test/atomicity/test_pair_instructions_within_transaction.py +++ b/client_cli/pytests/test/atomicity/test_pair_instructions_within_transaction.py @@ -1,6 +1,7 @@ import allure import pytest + @pytest.fixture(scope="function", autouse=True) def story_client_sends_pair_instructions_within_transaction(): allure.dynamic.story('Client sends a pair instructions within transaction') diff --git a/client_cli/pytests/test/atomicity/test_wrong_instructions_within_transaction.py b/client_cli/pytests/test/atomicity/test_wrong_instructions_within_transaction.py index 66422357536..5e1df2dcfeb 100644 --- a/client_cli/pytests/test/atomicity/test_wrong_instructions_within_transaction.py +++ b/client_cli/pytests/test/atomicity/test_wrong_instructions_within_transaction.py @@ -1,6 +1,7 @@ import allure import pytest + @pytest.fixture(scope="function", autouse=True) def story_send_pair_instructions_within_transaction(): allure.dynamic.story('Client sends a wrong instruction in transaction') diff --git a/client_cli/pytests/test/conftest.py b/client_cli/pytests/test/conftest.py index ec2bac20bb6..101612ef90e 100644 --- a/client_cli/pytests/test/conftest.py +++ b/client_cli/pytests/test/conftest.py @@ -1,4 +1,5 @@ # pylint: disable=redefined-outer-name +# pylint: disable=invalid-name """ This module contains pytest fixtures for testing. """ @@ -7,10 +8,20 @@ from common.consts import ValueTypes from common.helpers import * -from models import Account, AssetDefinition, Domain, Asset +from common.settings import PEERS_CONFIGS_PATH +from models import Account, Asset, AssetDefinition, Domain from src.client_cli import client_cli, config + # General fixtures +@pytest.fixture(scope='session', autouse=True) +def before_all(): + """Initial setup for all test sessions. + This fixture generates configurations based on peers and is automatically + used for every test session.""" + config.generate_by_peers(PEERS_CONFIGS_PATH) + yield + @pytest.fixture(scope='function', autouse=True) def before_each(): """Fixture to set up and reset the client_cli state.""" @@ -21,32 +32,32 @@ def before_each(): # Fixtures for creating objects (domains, accounts, asset definitions, assets) @pytest.fixture() -def GIVEN_new_one_existing_domain(): - """Fixture to create and register an existing domain.""" +def GIVEN_registered_domain(): + """Fixture to create and register a domain.""" domain = Domain(fake_name()) - with allure.step(f'GIVEN an existing domain {domain.name}'): + with allure.step(f'GIVEN a registered domain {domain.name}'): client_cli.register().domain(domain.name) return domain @pytest.fixture() -def GIVEN_existing_domain_with_uppercase_letter( - GIVEN_new_one_existing_domain): - """Fixture to create and register an existing domain, but with uppercase letter.""" - domain = GIVEN_new_one_existing_domain +def GIVEN_registered_domain_with_uppercase_letter( + GIVEN_registered_domain): + """Fixture to create and register a domain, but with uppercase letter.""" + domain = GIVEN_registered_domain domain.name = name_with_uppercase_letter(domain.name) - with allure.step(f'GIVEN an existing domain {domain.name}'): + with allure.step(f'GIVEN a registered domain {domain.name}'): client_cli.register().domain(domain.name) return domain @pytest.fixture() -def GIVEN_new_one_existing_account(GIVEN_new_one_existing_domain, GIVEN_public_key): - """Fixture to create and register an existing account.""" +def GIVEN_registered_account(GIVEN_registered_domain, GIVEN_public_key): + """Fixture to create an account.""" name = fake_name() account = Account( name=name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, public_key=GIVEN_public_key) - with allure.step(f'GIVEN the account "{name}" in the "{GIVEN_new_one_existing_domain.name}" domain'): + with allure.step(f'GIVEN the account "{name}" in the "{GIVEN_registered_domain.name}" domain'): client_cli.register().account( account=account.name, domain=account.domain, @@ -60,7 +71,8 @@ def GIVEN_currently_authorized_account(): name=config.account_name, domain=config.account_domain, public_key=config.public_key) - with allure.step(f'GIVEN the currently authorized account "{account.name}" in the "{account.domain}" domain'): + with allure.step(f'GIVEN the currently authorized account "{account.name}" ' + f'in the "{account.domain}" domain'): return account @pytest.fixture() @@ -72,7 +84,9 @@ def GIVEN_currently_account_quantity_with_two_quantity_of_asset( asset_def = AssetDefinition(name=GIVEN_fake_asset_name, domain=GIVEN_currently_authorized_account.domain, value_type=GIVEN_quantity_value_type) - asset = Asset(definition=asset_def, value='2') + asset = Asset(definition=asset_def, + value='2', + account=GIVEN_currently_authorized_account.name) name = fake_name() with allure.step(f'GIVEN the asset_definition "{name}" ' f'in the "{GIVEN_currently_authorized_account.domain}" domain'): @@ -87,35 +101,100 @@ def GIVEN_currently_account_quantity_with_two_quantity_of_asset( ) return asset +@pytest.fixture() +def GIVEN_quantity_asset_for_account( + request, + GIVEN_quantity_value_type, + GIVEN_fake_asset_name, + GIVEN_quantity_value): + """Fixture to get an asset for a given account and domain with specified quantity.""" + account, domain = request.param.split('@') + account = Account( + name=account, + domain=domain) + + asset_def = AssetDefinition(name=GIVEN_fake_asset_name, + domain=domain, + value_type=GIVEN_quantity_value_type) + asset = Asset(definition=asset_def, + value=GIVEN_quantity_value, + account=account.name) + + with allure.step(f'GIVEN the asset_definition "{asset_def.name}" ' + f'in the "{domain}" domain'): + client_cli.register().asset().definition( + asset=asset.definition.name, + domain=asset.definition.domain, + value_type=asset.definition.value_type) + client_cli.mint().asset( + account=account, + asset_definition=asset.definition, + value_of_value_type=asset.value) + + return asset + @pytest.fixture() -def GIVEN_existing_asset_definition_with_quantity_value_type( - GIVEN_new_one_existing_domain, +def GIVEN_registered_asset_definition_with_quantity_value_type( + GIVEN_registered_domain, GIVEN_quantity_value_type, GIVEN_fake_asset_name): - """Fixture to create and register an existing asset definition with random value type.""" + """Fixture to create and register an asset definition with quantity value type.""" asset_def = AssetDefinition(name=GIVEN_fake_asset_name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, value_type=GIVEN_quantity_value_type) with allure.step(f'GIVEN the asset_definition "{GIVEN_fake_asset_name}" ' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): + f'in the "{GIVEN_registered_domain.name}" domain'): client_cli.register().asset().definition(asset=asset_def.name, domain=asset_def.domain, value_type=asset_def.value_type) return asset_def @pytest.fixture() -def GIVEN_existing_asset_definition_with_store_value_type( - GIVEN_new_one_existing_domain, +def GIVEN_minted_asset_quantity( + GIVEN_registered_asset_definition_with_quantity_value_type, + GIVEN_registered_account, + GIVEN_quantity_value): + """Fixture to create and return an asset with a specified quantity. + It takes a registered asset definition, a registered account, and a quantity value.""" + asset = Asset(account=GIVEN_registered_account, + definition=GIVEN_registered_asset_definition_with_quantity_value_type, + value=GIVEN_quantity_value) + client_cli.mint().asset( + account=asset.account, + asset_definition=asset.definition, + value_of_value_type=asset.value + ) + return asset + +@pytest.fixture() +def GIVEN_registered_asset_definition_with_big_quantity_value_type( + GIVEN_registered_domain, + GIVEN_big_quantity_value_type, + GIVEN_fake_asset_name): + """Fixture to create and register an asset definition with big quantity value type.""" + asset_def = AssetDefinition(name=GIVEN_fake_asset_name, + domain=GIVEN_registered_domain.name, + value_type=GIVEN_big_quantity_value_type) + with allure.step(f'GIVEN the asset_definition "{GIVEN_fake_asset_name}" ' + f'in the "{GIVEN_registered_domain.name}" domain'): + client_cli.register().asset().definition(asset=asset_def.name, + domain=asset_def.domain, + value_type=asset_def.value_type) + return asset_def + +@pytest.fixture() +def GIVEN_registered_asset_definition_with_store_value_type( + GIVEN_registered_domain, GIVEN_store_value_type, GIVEN_fake_asset_name): - """Fixture to create and register an existing asset definition with store value type.""" + """Fixture to create and register an asset definition with store value type.""" asset_def = AssetDefinition(name=GIVEN_fake_asset_name, - domain=GIVEN_new_one_existing_domain.name, + domain=GIVEN_registered_domain.name, value_type=GIVEN_store_value_type) with allure.step(f'GIVEN the asset_definition "{GIVEN_fake_asset_name}" ' - f'in the "{GIVEN_new_one_existing_domain.name}" domain'): + f'in the "{GIVEN_registered_domain.name}" domain'): client_cli.register().asset().definition(asset=asset_def.name, domain=asset_def.domain, value_type=asset_def.value_type) @@ -160,8 +239,13 @@ def GIVEN_random_character(): @pytest.fixture() def GIVEN_random_invalid_base64_character(): - """Fixture to provide a random invalid base64 character (not a-z,A-Z,0-9,+,/,=).""" - letter = random.choice([ch for ch in string.printable if not (ch.isalpha() or ch.isdigit() or ch == "=" or ch == "+" or ch == "/")]) + """Fixture to provide a random invalid base64 character + (not a-z,A-Z,0-9,+,/,=). + """ + invalid_chars = [ch for ch in string.printable + if not (ch.isalpha() or ch.isdigit() + or ch in ["=", "+", "/"])] + letter = random.choice(invalid_chars) with allure.step(f'GIVEN a "{letter}" name'): return letter @@ -171,7 +255,9 @@ def GIVEN_key_with_invalid_character_in_key( GIVEN_public_key, GIVEN_random_invalid_base64_character): """Fixture to provide a public key with an invalid character.""" - invalid_key = key_with_invalid_character_in_key(GIVEN_public_key, GIVEN_random_invalid_base64_character) + invalid_key = key_with_invalid_character_in_key( + GIVEN_public_key, + GIVEN_random_invalid_base64_character) with allure.step(f'GIVEN an invalid key "{invalid_key}"'): return invalid_key @@ -189,28 +275,35 @@ def GIVEN_store_value_type(): with allure.step(f'GIVEN a "{value_type}" value type'): return value_type +@pytest.fixture() +def GIVEN_big_quantity_value_type(): + """Fixture to provide a big quantity value type.""" + value_type = ValueTypes.BIG_QUANTITY.value + with allure.step(f'GIVEN a "{value_type}" value type'): + return value_type + @pytest.fixture() def GIVEN_quantity_value(): """Fixture to provide a random quantity value based on the given value type.""" - rand_int = str(random.getrandbits(32)) + rand_int = str((random.getrandbits(32))-1) return rand_int @pytest.fixture() def GIVEN_128_lenght_name(): ident = generate_random_string_without_reserved_chars(128) - with allure.step(f'GIVEN a name with 128 lenght "{ident}"'): + with allure.step(f'GIVEN a name with 128 length "{ident}"'): return ident @pytest.fixture() def GIVEN_129_lenght_name(): ident = generate_random_string_without_reserved_chars(129) - with allure.step(f'GIVEN a name with 129 lenght "{ident}"'): + with allure.step(f'GIVEN a name with 129 length "{ident}"'): return ident @pytest.fixture() def GIVEN_127_lenght_name(): ident = generate_random_string_without_reserved_chars(127) - with allure.step(f'GIVEN a name with 127 lenght "{ident}"'): + with allure.step(f'GIVEN a name with 127 length "{ident}"'): return ident @pytest.fixture() @@ -226,4 +319,3 @@ def GIVEN_string_with_whitespaces(): new_string = generate_random_string_with_whitespace() with allure.step(f'GIVEN a "{new_string}" string'): return new_string - diff --git a/client_cli/pytests/test/domains/conftest.py b/client_cli/pytests/test/domains/conftest.py index 470411fe5a5..7ac0a156283 100644 --- a/client_cli/pytests/test/domains/conftest.py +++ b/client_cli/pytests/test/domains/conftest.py @@ -1,19 +1,14 @@ -import pytest +from test import (GIVEN_128_lenght_name, GIVEN_129_lenght_name, + GIVEN_currently_authorized_account, GIVEN_fake_name, + GIVEN_public_key, GIVEN_random_character, + GIVEN_registered_account, GIVEN_registered_domain, + GIVEN_registered_domain_with_uppercase_letter, + GIVEN_string_with_reserved_character, + GIVEN_string_with_whitespaces, before_all, before_each) + import allure +import pytest -from test import ( - GIVEN_128_lenght_name, - GIVEN_129_lenght_name, - GIVEN_new_one_existing_domain, - GIVEN_fake_name, - GIVEN_random_character, - GIVEN_string_with_reserved_character, - GIVEN_string_with_whitespaces, - GIVEN_existing_domain_with_uppercase_letter, - GIVEN_currently_authorized_account, - GIVEN_new_one_existing_account, - GIVEN_public_key, - before_each) @pytest.fixture(scope="function", autouse=True) def domain_test_setup(): diff --git a/client_cli/pytests/test/domains/test_domains_query_filters.py b/client_cli/pytests/test/domains/test_domains_query_filters.py index 95c7bcb8887..ee9eeaa6d32 100644 --- a/client_cli/pytests/test/domains/test_domains_query_filters.py +++ b/client_cli/pytests/test/domains/test_domains_query_filters.py @@ -1,11 +1,13 @@ import json + import allure -from src.client_cli import iroha, client_cli +from src.client_cli import client_cli, iroha + -def test_filter_by_domain(GIVEN_new_one_existing_domain): +def test_filter_by_domain(GIVEN_registered_domain): def condition(): - domain_name = GIVEN_new_one_existing_domain.name + domain_name = GIVEN_registered_domain.name with allure.step( f'WHEN client_cli query domains filtered by name "{domain_name}"'): domains = iroha.list_filter(f'{{"Identifiable": {{"Is": "{domain_name}"}}}}').domains() diff --git a/client_cli/pytests/test/domains/test_register_domains.py b/client_cli/pytests/test/domains/test_register_domains.py index df921966500..0dc926c318c 100644 --- a/client_cli/pytests/test/domains/test_register_domains.py +++ b/client_cli/pytests/test/domains/test_register_domains.py @@ -33,24 +33,24 @@ def test_register_empty_domain( @allure.label('sdk_test_id', 'register_existing_domain') def test_register_existing_domain( - GIVEN_new_one_existing_domain): + GIVEN_registered_domain): with allure.step( - f'WHEN client_cli registers an existing domain "{GIVEN_new_one_existing_domain.name}"'): - client_cli.register().domain(GIVEN_new_one_existing_domain.name) + f'WHEN client_cli registers an existing domain "{GIVEN_registered_domain.name}"'): + client_cli.register().domain(GIVEN_registered_domain.name) with allure.step( - f'THEN client_cli should have the domain error: "{GIVEN_new_one_existing_domain.name}"'): + f'THEN client_cli should have the domain error: "{GIVEN_registered_domain.name}"'): client_cli.should(have.error(Stderr.REPETITION.value)) @allure.label('sdk_test_id', 'register_existing_domain_with_uppercase_letter') def test_register_existing_domain_uppercase_with_uppercase_letter( - GIVEN_existing_domain_with_uppercase_letter): + GIVEN_registered_domain_with_uppercase_letter): with allure.step( f'WHEN client_cli registers an existing domain, ' - f'but with uppercase letter "{GIVEN_existing_domain_with_uppercase_letter.name}"'): - client_cli.register().domain(GIVEN_existing_domain_with_uppercase_letter.name) + f'but with uppercase letter "{GIVEN_registered_domain_with_uppercase_letter.name}"'): + client_cli.register().domain(GIVEN_registered_domain_with_uppercase_letter.name) with allure.step( - f'THEN Iroha should have the domain name "{GIVEN_existing_domain_with_uppercase_letter.name}"'): - iroha.should(have.domain(GIVEN_existing_domain_with_uppercase_letter.name)) + f'THEN Iroha should have the domain name "{GIVEN_registered_domain_with_uppercase_letter.name}"'): + iroha.should(have.domain(GIVEN_registered_domain_with_uppercase_letter.name)) @allure.label('sdk_test_id', 'register_one_letter_domain') def test_register_one_letter_domain( diff --git a/client_cli/pytests/test/domains/test_transfer_domains.py b/client_cli/pytests/test/domains/test_transfer_domains.py index ac8cb4d0f3d..bfdd8ff1ad0 100644 --- a/client_cli/pytests/test/domains/test_transfer_domains.py +++ b/client_cli/pytests/test/domains/test_transfer_domains.py @@ -1,7 +1,8 @@ import allure import pytest -from src.client_cli import client_cli, iroha, have +from src.client_cli import client_cli, have, iroha + @pytest.fixture(scope="function", autouse=True) def story_account_transfers_domain(): @@ -11,16 +12,16 @@ def story_account_transfers_domain(): @allure.label('sdk_test_id', 'transfer_domain_successfully') def test_transfer_domain( GIVEN_currently_authorized_account, - GIVEN_new_one_existing_account, - GIVEN_new_one_existing_domain, + GIVEN_registered_account, + GIVEN_registered_domain, ): with allure.step( f'WHEN {GIVEN_currently_authorized_account} transfers domains ' - f'to {GIVEN_new_one_existing_account}'): + f'to {GIVEN_registered_account}'): client_cli.execute(f'domain transfer ' f'--from={GIVEN_currently_authorized_account} ' - f'--to={GIVEN_new_one_existing_account} ' - f'--id={GIVEN_new_one_existing_domain.name}') + f'--to={GIVEN_registered_account} ' + f'--id={GIVEN_registered_domain.name}') with allure.step( - f'THEN {GIVEN_new_one_existing_account} should own {GIVEN_new_one_existing_domain}'): - iroha.should(have.domain(GIVEN_new_one_existing_domain.name, owned_by=GIVEN_new_one_existing_account)) + f'THEN {GIVEN_registered_account} should own {GIVEN_registered_domain}'): + iroha.should(have.domain(GIVEN_registered_domain.name, owned_by=GIVEN_registered_account)) diff --git a/client_cli/pytests/test/roles/conftest.py b/client_cli/pytests/test/roles/conftest.py index 3e68a370cae..44cb325154e 100644 --- a/client_cli/pytests/test/roles/conftest.py +++ b/client_cli/pytests/test/roles/conftest.py @@ -1,10 +1,9 @@ -import pytest +from test import GIVEN_fake_name, before_all, before_each + import allure +import pytest -from test import ( - GIVEN_fake_name, - before_each) @pytest.fixture(scope="function", autouse=True) -def permission_test_setup(): +def role_test_setup(): allure.dynamic.feature('Roles') diff --git a/client_cli/pytests/test/roles/test_register_roles.py b/client_cli/pytests/test/roles/test_register_roles.py index 84d5d3a32b6..c476c3a6137 100644 --- a/client_cli/pytests/test/roles/test_register_roles.py +++ b/client_cli/pytests/test/roles/test_register_roles.py @@ -1,6 +1,7 @@ import allure import pytest + @pytest.fixture(scope="function", autouse=True) def story_account_registers_roles(): allure.dynamic.story('Account registers a role') @@ -17,7 +18,7 @@ def test_register_role( @allure.label('sdk_test_id', 'attach_permissions_to_role') @pytest.mark.xfail(reason="TO DO") def test_attach_permissions_to_role( - GIVEN_existing_asset_definition_with_store_value_type): + GIVEN_registered_asset_definition_with_store_value_type): assert 0 @@ -25,6 +26,6 @@ def test_attach_permissions_to_role( @pytest.mark.xfail(reason="TO DO") def test_grant_role_to_account( GIVEN_currently_authorized_account, - GIVEN_new_one_existing_account, - GIVEN_existing_asset_definition_with_store_value_type): + GIVEN_registered_account, + GIVEN_registered_asset_definition_with_store_value_type): assert 0 diff --git a/client_cli/pytests/test/triggers/conftest.py b/client_cli/pytests/test/triggers/conftest.py new file mode 100644 index 00000000000..5a8df78eedb --- /dev/null +++ b/client_cli/pytests/test/triggers/conftest.py @@ -0,0 +1,9 @@ +from test import GIVEN_currently_authorized_account + +import allure +import pytest + + +@pytest.fixture(scope="function", autouse=True) +def trigger_test_setup(): + allure.dynamic.feature('Triggers') diff --git a/client_cli/pytests/test/triggers/test_register_trigger.py b/client_cli/pytests/test/triggers/test_register_trigger.py new file mode 100644 index 00000000000..b27aaf96a96 --- /dev/null +++ b/client_cli/pytests/test/triggers/test_register_trigger.py @@ -0,0 +1,22 @@ +import allure +import pytest + +from src.client_cli import client_cli, have, iroha + + +@pytest.fixture(scope="function", autouse=True) +def story_account_registers_trigger(): + allure.dynamic.story('Account register a register_trigger') + allure.dynamic.label('permission', 'no_permission_required') + + +@allure.label('sdk_test_id', 'register_trigger') +@pytest.mark.xfail(reason="wait for #4151") +def test_register_trigger( + GIVEN_currently_authorized_account): + with allure.step( + f'WHEN client_cli registers a register_trigger for "{GIVEN_currently_authorized_account}"'): + client_cli.register_trigger(GIVEN_currently_authorized_account) + with allure.step( + f'THEN Iroha should have the asset with nft_number_1_for_genesis##genesis@genesis'): + iroha.should(have.asset('nft_number_1_for_genesis##genesis@genesis'))