Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: add new tests with main chain #947

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? You can always set the ones you want and it's ok to have none by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is based on https://github.com/nspcc-dev/neofs-dev-env/blob/master/services/chain/protocol.privnet1.yml configs, where Genesis part is omitted in case of a single IR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't affect the result in our case, but still that's not the way mainnet/testnet work.

{%- 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
Loading