Skip to content

Commit

Permalink
tests: add tests with main chain
Browse files Browse the repository at this point in the history
closes #943

Signed-off-by: Evgeniy Zayats <[email protected]>
  • Loading branch information
Evgeniy Zayats committed Feb 12, 2025
1 parent 32fba65 commit fc20f20
Show file tree
Hide file tree
Showing 11 changed files with 341 additions and 99 deletions.
102 changes: 75 additions & 27 deletions neofs-testlib/neofs_testlib/env/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,25 +241,49 @@ def deploy_neofs_contract(self):
"There should be at least a single IR instance configured(not started) to deploy neofs contract"
)
neo_go = self.neo_go()
neo_go.nep17.balance(
self.main_chain.wallet.address,
"GAS",
f"http://{self.main_chain.rpc_address}",
wallet_config=self.main_chain.neo_go_config,
)
neo_go.nep17.transfer(
"GAS",
self.default_wallet.address,
f"http://{self.main_chain.rpc_address}",
from_address=self.inner_ring_nodes[-1].alphabet_wallet.address,
from_address=self.main_chain.wallet.address,
amount=9000,
force=True,
wallet_config=self.main_chain.neo_go_config,
await_=True,
)
ir_alphabet_pubkey_from_neogo = wallet_utils.get_last_public_key_from_wallet_with_neogo(
self.neo_go(), self.inner_ring_nodes[-1].alphabet_wallet.path

for ir_node in self.inner_ring_nodes:
accounts = wallet_utils.get_accounts_from_wallet(ir_node.alphabet_wallet.path, self.default_password)
for acc in accounts:
neo_go.nep17.transfer(
"GAS",
acc.address,
f"http://{self.main_chain.rpc_address}",
from_address=self.main_chain.wallet.address,
amount=9000,
force=True,
wallet_config=self.main_chain.neo_go_config,
await_=True,
)

pub_keys_of_existing_ir_nodes = " ".join(
wallet_utils.get_last_public_key_from_wallet_with_neogo(
self.neo_go(),
ir_node.alphabet_wallet.path,
).splitlines()
)
result = neo_go.contract.deploy(
input_file=f"{self.neofs_contract_dir}/neofs/neofs_contract.nef",
manifest=f"{self.neofs_contract_dir}/neofs/config.json",
force=True,
rpc_endpoint=f"http://{self.main_chain.rpc_address}",
post_data=f"[ true ffffffffffffffffffffffffffffffffffffffff [ {ir_alphabet_pubkey_from_neogo} ] [ InnerRingCandidateFee 10 WithdrawFee 10 ] ]",
post_data=f"[ true ffffffffffffffffffffffffffffffffffffffff [ {pub_keys_of_existing_ir_nodes} ] [ InnerRingCandidateFee 10 WithdrawFee 10 ] ]",
wallet_config=self.default_wallet_neogo_config,
)
contract_hash = result.stdout.split("Contract: ")[-1].strip()
Expand Down Expand Up @@ -306,34 +330,34 @@ def generate_storage_wallet(

@allure.step("Generate alphabet wallets")
def generate_alphabet_wallets(
self,
network_config: Optional[str] = None,
size: Optional[int] = 1,
self, network_config: Optional[str] = None, size: Optional[int] = 1, alphabet_wallets_dir: Optional[str] = None
) -> list[NodeWallet]:
neofs_adm = self.neofs_adm(network_config)

neofs_adm.fschain.generate_alphabet(alphabet_wallets=self.alphabet_wallets_dir, size=size)
if not alphabet_wallets_dir:
alphabet_wallets_dir = self.alphabet_wallets_dir
neofs_adm.fschain.generate_alphabet(alphabet_wallets=alphabet_wallets_dir, size=size)

generated_wallets = []

for generated_wallet in os.listdir(self.alphabet_wallets_dir):
for generated_wallet in os.listdir(alphabet_wallets_dir):
# neo3 package requires some attributes to be set
with open(os.path.join(self.alphabet_wallets_dir, generated_wallet), "r") as wallet_file:
with open(os.path.join(alphabet_wallets_dir, generated_wallet), "r") as wallet_file:
wallet_json = json.load(wallet_file)

wallet_json["name"] = None
for acc in wallet_json["accounts"]:
acc["extra"] = None

with open(os.path.join(self.alphabet_wallets_dir, generated_wallet), "w") as wallet_file:
with open(os.path.join(alphabet_wallets_dir, generated_wallet), "w") as wallet_file:
json.dump(wallet_json, wallet_file)

generated_wallets.append(
NodeWallet(
path=os.path.join(self.alphabet_wallets_dir, generated_wallet),
path=os.path.join(alphabet_wallets_dir, generated_wallet),
password=self.default_password,
address=wallet_utils.get_last_address_from_wallet(
os.path.join(self.alphabet_wallets_dir, generated_wallet), self.default_password
os.path.join(alphabet_wallets_dir, generated_wallet), self.default_password
),
)
)
Expand Down Expand Up @@ -686,6 +710,8 @@ def __init__(self, neofs_env: NeoFSEnv):
self.p2p_address = f"{self.neofs_env.domain}:{NeoFSEnv.get_available_port()}"
self.pprof_address = f"{self.neofs_env.domain}:{NeoFSEnv.get_available_port()}"
self.prometheus_address = f"{self.neofs_env.domain}:{NeoFSEnv.get_available_port()}"
self.wallet_dir = self.neofs_env._generate_temp_dir(prefix="mainchain_wallet")
self.wallet = None
self.stdout = "Not initialized"
self.stderr = "Not initialized"
self.process = None
Expand Down Expand Up @@ -715,21 +741,31 @@ def start(self, wait_until_ready=True):
if self.process is not None:
raise RuntimeError("This main chain instance has already been started")

alphabet_wallet = self.neofs_env.inner_ring_nodes[-1].alphabet_wallet
self.wallet = self.neofs_env.generate_alphabet_wallets(alphabet_wallets_dir=self.wallet_dir)[0]

standby_committee = wallet_utils.get_last_public_key_from_wallet_with_neogo(
self.neofs_env.neo_go(), self.wallet.path
)

ir_alphabet_pubkey_from_neogo = wallet_utils.get_last_public_key_from_wallet_with_neogo(
self.neofs_env.neo_go(), alphabet_wallet.path
self.neofs_env.neo_go(), self.neofs_env.inner_ring_nodes[-1].alphabet_wallet.path
)

if len(self.neofs_env.inner_ring_nodes) > 1:
ir_public_keys = ir_alphabet_pubkey_from_neogo.splitlines()
else:
ir_public_keys = [ir_alphabet_pubkey_from_neogo]

logger.info(f"Generating main chain config at: {self.main_chain_config_path}")
main_chain_config_template = "main_chain.yaml"

NeoFSEnv.generate_config_file(
config_template=main_chain_config_template,
config_path=self.main_chain_config_path,
custom=Path(main_chain_config_template).is_file(),
wallet=alphabet_wallet,
public_key=ir_alphabet_pubkey_from_neogo,
wallet=self.wallet,
standby_committee=standby_committee,
ir_public_keys=ir_public_keys,
main_chain_boltdb=self.main_chain_boltdb,
p2p_address=self.p2p_address,
rpc_address=self.rpc_address,
Expand All @@ -738,12 +774,10 @@ def start(self, wait_until_ready=True):
prometheus_address=self.prometheus_address,
)
logger.info(f"Generating CLI config at: {self.cli_config}")
NeoFSEnv.generate_config_file(
config_template="cli_cfg.yaml", config_path=self.cli_config, wallet=alphabet_wallet
)
NeoFSEnv.generate_config_file(config_template="cli_cfg.yaml", config_path=self.cli_config, wallet=self.wallet)
logger.info(f"Generating NEO GO config at: {self.neo_go_config}")
NeoFSEnv.generate_config_file(
config_template="neo_go_cfg.yaml", config_path=self.neo_go_config, wallet=alphabet_wallet
config_template="neo_go_cfg.yaml", config_path=self.neo_go_config, wallet=self.wallet
)
logger.info(f"Launching Main Chain:{self}")
self._launch_process()
Expand Down Expand Up @@ -839,18 +873,31 @@ def generate_cli_config(self):
)

@allure.step("Start Inner Ring node")
def start(self, wait_until_ready=True, with_main_chain=False):
def start(
self,
wait_until_ready=True,
with_main_chain=False,
pub_keys_of_existing_ir_nodes=None,
seed_node_addresses_of_existing_ir_nodes=None,
fschain_autodeploy=True,
):
if self.process is not None:
raise RuntimeError("This inner ring node instance has already been started")
logger.info(f"Generating IR config at: {self.ir_node_config_path}")
ir_config_template = "ir.yaml"

pub_keys_of_existing_ir_nodes = [
wallet_utils.get_last_public_key_from_wallet(ir_node.alphabet_wallet.path, ir_node.alphabet_wallet.password)
for ir_node in self.neofs_env.inner_ring_nodes
]
if not pub_keys_of_existing_ir_nodes:
pub_keys_of_existing_ir_nodes = [
wallet_utils.get_last_public_key_from_wallet(
ir_node.alphabet_wallet.path, ir_node.alphabet_wallet.password
)
for ir_node in self.neofs_env.inner_ring_nodes
]

seed_node_addresses_of_existing_ir_nodes = [ir_node.p2p_address for ir_node in self.neofs_env.inner_ring_nodes]
if not seed_node_addresses_of_existing_ir_nodes:
seed_node_addresses_of_existing_ir_nodes = [
ir_node.p2p_address for ir_node in self.neofs_env.inner_ring_nodes
]

NeoFSEnv.generate_config_file(
config_template=ir_config_template,
Expand All @@ -868,6 +915,7 @@ def start(self, wait_until_ready=True, with_main_chain=False):
len(self.neofs_env.inner_ring_nodes) - (len(self.neofs_env.inner_ring_nodes) - 1) / 3 - 1
),
set_roles_in_genesis=str(False if len(self.neofs_env.inner_ring_nodes) == 1 else True).lower(),
fschain_autodeploy=fschain_autodeploy,
control_public_key=wallet_utils.get_last_public_key_from_wallet(
self.alphabet_wallet.path, self.alphabet_wallet.password
),
Expand Down
2 changes: 1 addition & 1 deletion neofs-testlib/neofs_testlib/env/templates/ir.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fschain:
min: {{ peers_min_number }}
set_roles_in_genesis: {{ set_roles_in_genesis }}

fschain_autodeploy: true
fschain_autodeploy: {{ fschain_autodeploy }}

nns:
system_email: [email protected]
Expand Down
8 changes: 7 additions & 1 deletion neofs-testlib/neofs_testlib/env/templates/main_chain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ ProtocolConfiguration:
TimePerBlock: 1s
MemPoolSize: 50000
StandbyCommittee:
- {{ public_key }}
- {{ standby_committee }}
ValidatorsCount: 1
VerifyTransactions: true
P2PSigExtensions: false
Genesis:
Roles:
NeoFSAlphabet:
{%- for public_key in ir_public_keys %}
- {{ public_key }}
{%- endfor %}

ApplicationConfiguration:
SkipBlockVerification: false
Expand Down
24 changes: 24 additions & 0 deletions neofs-testlib/neofs_testlib/utils/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from neo3.wallet import account as neo3_account
from neo3.wallet import wallet as neo3_wallet

from neofs_testlib.cli.neogo import NeoGo

logger = logging.getLogger("neofs.testlib.utils")
Expand Down Expand Up @@ -49,6 +50,29 @@ def get_last_address_from_wallet(
return address


def get_accounts_from_wallet(
wallet_path: str, wallet_password: str | None = None, wallet_passwords: list[str] | None = None
):
"""
Extracting the last address from the given wallet.
Args:
wallet_path: The path to the wallet to extract address from.
wallet_password: The password for the given wallet.
wallet_passwords: The password list for the given accounts in the wallet
Returns:
The address for the wallet.
"""
if wallet_password is None and wallet_passwords is None:
raise ValueError("Either wallet_password or wallet_passwords should be specified")

with open(wallet_path) as wallet_file:
wallet_json = json.load(wallet_file)
if wallet_password is not None:
wallet_passwords = [wallet_password] * len(wallet_json["accounts"])
wallet = neo3_wallet.Wallet.from_json(wallet_json, passwords=wallet_passwords)
return wallet.accounts


def get_last_public_key_from_wallet(
wallet_path: str, wallet_password: str | None = None, wallet_passwords: list[str] | None = None
):
Expand Down
7 changes: 7 additions & 0 deletions pytest_tests/lib/helpers/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,10 @@ def wait_for_gc_pass_on_storage_nodes() -> None:
wait_time = parse_time(STORAGE_GC_TIME)
with allure.step(f"Wait {wait_time}s until GC completes on storage nodes"):
time.sleep(wait_time)


def parse_node_height(stdout: str) -> tuple[float, float]:
lines = stdout.strip().split("\n")
block_height = float(lines[0].split(": ")[1].strip())
state = float(lines[1].split(": ")[1].strip())
return block_height, state
51 changes: 51 additions & 0 deletions pytest_tests/lib/helpers/wallet_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,54 @@ def wait_for_correct_wallet_balance(
assert compare_func(get_wallet_balance(neofs_env, neo_go, wallet, neo_go_wallet_config)), (
"Wallet balance is not correct after"
)


def create_wallet_with_money(neofs_env_with_mainchain: NeoFSEnv) -> NodeWallet:
neofs_env = neofs_env_with_mainchain

with allure.step("Create wallet for deposit"):
wallet = NodeWallet(
path=neofs_env_with_mainchain._generate_temp_file(
neofs_env._env_dir, prefix="deposit_withdrawal_test_wallet"
),
address="",
password=neofs_env.default_password,
)
init_wallet(wallet.path, wallet.password)
wallet.address = get_last_address_from_wallet(wallet.path, wallet.password)
wallet.neo_go_config = neofs_env.generate_neo_go_config(wallet)
wallet.cli_config = neofs_env.generate_cli_config(wallet)

with allure.step("Transfer some money to created wallet"):
neo_go = neofs_env.neo_go()
neo_go.nep17.transfer(
"GAS",
wallet.address,
f"http://{neofs_env.main_chain.rpc_address}",
from_address=neofs_env.main_chain.wallet.address,
amount=1000,
force=True,
wallet_config=neofs_env.main_chain.neo_go_config,
await_=True,
)
assert get_wallet_balance(neofs_env, neo_go, wallet, wallet.neo_go_config) == 1000.0, (
"Money transfer from alphabet to test wallet didn't succeed"
)

with allure.step("Deposit money to neofs contract"):
neo_go.nep17.transfer(
"GAS",
neofs_env.main_chain.neofs_contract_address,
f"http://{neofs_env.main_chain.rpc_address}",
from_address=wallet.address,
amount=100,
force=True,
wallet_config=wallet.neo_go_config,
await_=True,
)
assert get_wallet_balance(neofs_env, neo_go, wallet, wallet.neo_go_config) <= 900, (
"Wallet balance is not correct after deposit"
)
wait_for_correct_neofs_balance(neofs_env, wallet, wallet.cli_config, lambda balance: balance == 100)

return wallet
7 changes: 7 additions & 0 deletions pytest_tests/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,13 @@ def neofs_env_with_mainchain(request):
NeoFSEnv.cleanup_unused_ports()


@pytest.fixture
def clear_neofs_env():
neofs_env = NeoFSEnv(neofs_env_config=NeoFSEnv._generate_default_neofs_env_config())
yield neofs_env
neofs_env.kill()


@pytest.fixture(scope="module", autouse=True)
def cleanup_temp_files():
yield
Expand Down
Loading

0 comments on commit fc20f20

Please sign in to comment.