Compare commits
15 commits
master
...
support/v0
Author | SHA1 | Date | |
---|---|---|---|
56fcbe8b77 | |||
bef01eec48 | |||
14316c1fd7 | |||
a1ab09a074 | |||
4a9e3facff | |||
2140ce7f89 | |||
1ec6540063 | |||
72d30c7e06 | |||
431902c118 | |||
b66d04faf8 | |||
e3b27a7643 | |||
26962617c9 | |||
24fdcd88df | |||
4eb4963f17 | |||
af9c726624 |
28 changed files with 403 additions and 255 deletions
|
@ -164,3 +164,15 @@ def get_file_content(
|
||||||
content = file.read()
|
content = file.read()
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize_for_file_name(string: str) -> str:
|
||||||
|
"""
|
||||||
|
Returns string with only alpha num string with all other characters replaced by '_'
|
||||||
|
which is valid string to use as file name
|
||||||
|
|
||||||
|
Args:
|
||||||
|
string: string to sanitize
|
||||||
|
"""
|
||||||
|
|
||||||
|
return "".join(character if character.isalnum() else "_" for character in string).strip("_")
|
||||||
|
|
|
@ -5,7 +5,6 @@ from time import sleep
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
|
|
||||||
from remote_process import RemoteProcess
|
from remote_process import RemoteProcess
|
||||||
|
|
||||||
EXIT_RESULT_CODE = 0
|
EXIT_RESULT_CODE = 0
|
||||||
|
|
|
@ -41,9 +41,7 @@ class RemoteProcess:
|
||||||
Returns:
|
Returns:
|
||||||
RemoteProcess instance for further examination
|
RemoteProcess instance for further examination
|
||||||
"""
|
"""
|
||||||
remote_process = cls(
|
remote_process = cls(cmd=command, process_dir=f"/tmp/proc_{uuid.uuid4()}", shell=shell)
|
||||||
cmd=command, process_dir=f"/tmp/proc_{uuid.uuid4()}", shell=shell
|
|
||||||
)
|
|
||||||
remote_process._create_process_dir()
|
remote_process._create_process_dir()
|
||||||
remote_process._generate_command_script(command)
|
remote_process._generate_command_script(command)
|
||||||
remote_process._start_process()
|
remote_process._start_process()
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
|
import yaml
|
||||||
from common import STORAGE_GC_TIME
|
from common import STORAGE_GC_TIME
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
|
|
||||||
|
|
||||||
def parse_time(value: str) -> int:
|
def parse_time(value: str) -> int:
|
||||||
|
@ -60,3 +64,16 @@ def wait_for_gc_pass_on_storage_nodes() -> None:
|
||||||
wait_time = parse_time(STORAGE_GC_TIME)
|
wait_time = parse_time(STORAGE_GC_TIME)
|
||||||
with allure.step(f"Wait {wait_time}s until GC completes on storage nodes"):
|
with allure.step(f"Wait {wait_time}s until GC completes on storage nodes"):
|
||||||
time.sleep(wait_time)
|
time.sleep(wait_time)
|
||||||
|
|
||||||
|
|
||||||
|
def get_wallet_password(hosting: Hosting, service_name: str) -> Optional[str]:
|
||||||
|
service_config = hosting.get_service_config(service_name)
|
||||||
|
return service_config.attributes.get("wallet_password")
|
||||||
|
|
||||||
|
|
||||||
|
def create_wallet_config(hosting: Hosting, service_name: str) -> Optional[str]:
|
||||||
|
password = get_wallet_password(hosting=hosting, service_name=service_name)
|
||||||
|
wallet_config_path = os.path.join(os.getcwd(), f"{service_name}_wallet_config.yml")
|
||||||
|
with open(wallet_config_path, "w") as file:
|
||||||
|
yaml.dump({"password": password}, file)
|
||||||
|
return wallet_config_path
|
||||||
|
|
|
@ -6,6 +6,8 @@ log_format = %(asctime)s [%(levelname)4s] %(message)s
|
||||||
log_cli_date_format = %Y-%m-%d %H:%M:%S
|
log_cli_date_format = %Y-%m-%d %H:%M:%S
|
||||||
log_date_format = %H:%M:%S
|
log_date_format = %H:%M:%S
|
||||||
markers =
|
markers =
|
||||||
|
# controller markers
|
||||||
|
no_log_analyze: skip critical errors analyzer at the end of test
|
||||||
# special markers
|
# special markers
|
||||||
sanity: small tests subset
|
sanity: small tests subset
|
||||||
staging: test to be excluded from run in verifier/pr-validation/sanity jobs and run test in staging job
|
staging: test to be excluded from run in verifier/pr-validation/sanity jobs and run test in staging job
|
||||||
|
|
|
@ -1,68 +1 @@
|
||||||
aiodns==3.0.0
|
-r ../requirements.txt
|
||||||
aiohttp==3.7.4.post0
|
|
||||||
aioresponses==0.7.2
|
|
||||||
allure-pytest==2.9.45
|
|
||||||
allure-python-commons==2.9.45
|
|
||||||
async-timeout==3.0.1
|
|
||||||
asynctest==0.13.0
|
|
||||||
attrs==21.4.0
|
|
||||||
base58==2.1.0
|
|
||||||
bitarray==2.3.4
|
|
||||||
black==22.8.0
|
|
||||||
boto3==1.16.33
|
|
||||||
botocore==1.19.33
|
|
||||||
certifi==2022.5.18
|
|
||||||
cffi==1.15.0
|
|
||||||
chardet==4.0.0
|
|
||||||
charset-normalizer==2.0.12
|
|
||||||
coverage==6.3.3
|
|
||||||
docker==4.4.0
|
|
||||||
docutils==0.17.1
|
|
||||||
Events==0.4
|
|
||||||
flake8==4.0.1
|
|
||||||
idna==3.3
|
|
||||||
iniconfig==1.1.1
|
|
||||||
isort==5.10.1
|
|
||||||
jmespath==0.10.0
|
|
||||||
jsonschema==4.5.1
|
|
||||||
lz4==3.1.3
|
|
||||||
mccabe==0.6.1
|
|
||||||
mmh3==3.0.0
|
|
||||||
multidict==6.0.2
|
|
||||||
mypy==0.950
|
|
||||||
mypy-extensions==0.4.3
|
|
||||||
neo-mamba==0.10.0
|
|
||||||
neo3crypto==0.2.1
|
|
||||||
neo3vm==0.9.0
|
|
||||||
neo3vm-stubs==0.9.0
|
|
||||||
neofs-testlib==0.3.0
|
|
||||||
netaddr==0.8.0
|
|
||||||
orjson==3.6.8
|
|
||||||
packaging==21.3
|
|
||||||
paramiko==2.10.3
|
|
||||||
pexpect==4.8.0
|
|
||||||
pluggy==1.0.0
|
|
||||||
pre-commit==2.20.0
|
|
||||||
ptyprocess==0.7.0
|
|
||||||
py==1.11.0
|
|
||||||
pybiginteger==1.2.6
|
|
||||||
pybiginteger-stubs==1.2.6
|
|
||||||
pycares==4.1.2
|
|
||||||
pycodestyle==2.8.0
|
|
||||||
pycparser==2.21
|
|
||||||
pycryptodome==3.11.0
|
|
||||||
pyflakes==2.4.0
|
|
||||||
pyparsing==3.0.9
|
|
||||||
pyrsistent==0.18.1
|
|
||||||
pytest==7.1.2
|
|
||||||
python-dateutil==2.8.2
|
|
||||||
requests==2.28.0
|
|
||||||
robotframework==4.1.2
|
|
||||||
s3transfer==0.3.7
|
|
||||||
six==1.16.0
|
|
||||||
tenacity==8.0.1
|
|
||||||
tomli==2.0.1
|
|
||||||
typing-extensions==4.2.0
|
|
||||||
urllib3==1.26.9
|
|
||||||
websocket-client==1.3.2
|
|
||||||
yarl==1.7.2
|
|
||||||
|
|
|
@ -3,11 +3,10 @@ from dataclasses import asdict
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
from common import STORAGE_NODE_SERVICE_NAME_REGEX
|
from common import STORAGE_NODE_SERVICE_NAME_REGEX
|
||||||
|
from k6 import K6, LoadParams, LoadResults
|
||||||
from neofs_testlib.hosting import Hosting
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import SSHShell
|
from neofs_testlib.shell import SSHShell
|
||||||
|
|
||||||
from k6 import K6, LoadParams, LoadResults
|
|
||||||
|
|
||||||
|
|
||||||
@allure.title("Get services endpoints")
|
@allure.title("Get services endpoints")
|
||||||
def get_services_endpoints(
|
def get_services_endpoints(
|
||||||
|
|
|
@ -12,14 +12,9 @@ import urllib3
|
||||||
from botocore.config import Config
|
from botocore.config import Config
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
from cli_helpers import _cmd_run, _configure_aws_cli, _run_with_passwd
|
from cli_helpers import _cmd_run, _configure_aws_cli, _run_with_passwd
|
||||||
from common import (
|
from common import NEOFS_AUTHMATE_EXEC, NEOFS_ENDPOINT, S3_GATE, S3_GATE_WALLET_PATH
|
||||||
NEOFS_AUTHMATE_EXEC,
|
|
||||||
NEOFS_ENDPOINT,
|
|
||||||
S3_GATE,
|
|
||||||
S3_GATE_WALLET_PASS,
|
|
||||||
S3_GATE_WALLET_PATH,
|
|
||||||
)
|
|
||||||
from data_formatters import get_wallet_public_key
|
from data_formatters import get_wallet_public_key
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from python_keywords.container import list_containers
|
from python_keywords.container import list_containers
|
||||||
|
|
||||||
|
@ -43,7 +38,7 @@ class TestS3GateBase:
|
||||||
|
|
||||||
@pytest.fixture(scope="class", autouse=True)
|
@pytest.fixture(scope="class", autouse=True)
|
||||||
@allure.title("[Class/Autouse]: Create S3 client")
|
@allure.title("[Class/Autouse]: Create S3 client")
|
||||||
def s3_client(self, prepare_wallet_and_deposit, client_shell: Shell, request):
|
def s3_client(self, prepare_wallet_and_deposit, client_shell: Shell, request, hosting: Hosting):
|
||||||
wallet = prepare_wallet_and_deposit
|
wallet = prepare_wallet_and_deposit
|
||||||
s3_bearer_rules_file = f"{os.getcwd()}/robot/resources/files/s3_bearer_rules.json"
|
s3_bearer_rules_file = f"{os.getcwd()}/robot/resources/files/s3_bearer_rules.json"
|
||||||
|
|
||||||
|
@ -53,7 +48,7 @@ class TestS3GateBase:
|
||||||
access_key_id,
|
access_key_id,
|
||||||
secret_access_key,
|
secret_access_key,
|
||||||
owner_private_key,
|
owner_private_key,
|
||||||
) = init_s3_credentials(wallet, s3_bearer_rules_file=s3_bearer_rules_file)
|
) = init_s3_credentials(wallet, hosting, s3_bearer_rules_file=s3_bearer_rules_file)
|
||||||
containers_list = list_containers(wallet, shell=client_shell)
|
containers_list = list_containers(wallet, shell=client_shell)
|
||||||
assert cid in containers_list, f"Expected cid {cid} in {containers_list}"
|
assert cid in containers_list, f"Expected cid {cid} in {containers_list}"
|
||||||
|
|
||||||
|
@ -65,11 +60,22 @@ class TestS3GateBase:
|
||||||
TestS3GateBase.wallet = wallet
|
TestS3GateBase.wallet = wallet
|
||||||
|
|
||||||
|
|
||||||
|
def get_wallet_password(hosting: Hosting, s3_service_name: str) -> str:
|
||||||
|
service_config = hosting.get_service_config(s3_service_name)
|
||||||
|
return service_config.attributes.get("wallet_password")
|
||||||
|
|
||||||
|
|
||||||
@allure.step("Init S3 Credentials")
|
@allure.step("Init S3 Credentials")
|
||||||
def init_s3_credentials(wallet_path: str, s3_bearer_rules_file: Optional[str] = None):
|
def init_s3_credentials(
|
||||||
|
wallet_path: str,
|
||||||
|
hosting: Hosting,
|
||||||
|
s3_bearer_rules_file: Optional[str] = None,
|
||||||
|
s3_service_name: str = "s3-gate01",
|
||||||
|
):
|
||||||
bucket = str(uuid.uuid4())
|
bucket = str(uuid.uuid4())
|
||||||
s3_bearer_rules = s3_bearer_rules_file or "robot/resources/files/s3_bearer_rules.json"
|
s3_bearer_rules = s3_bearer_rules_file or "robot/resources/files/s3_bearer_rules.json"
|
||||||
gate_public_key = get_wallet_public_key(S3_GATE_WALLET_PATH, S3_GATE_WALLET_PASS)
|
s3_password = get_wallet_password(hosting, s3_service_name)
|
||||||
|
gate_public_key = get_wallet_public_key(S3_GATE_WALLET_PATH, s3_password)
|
||||||
cmd = (
|
cmd = (
|
||||||
f"{NEOFS_AUTHMATE_EXEC} --debug --with-log --timeout {CREDENTIALS_CREATE_TIMEOUT} "
|
f"{NEOFS_AUTHMATE_EXEC} --debug --with-log --timeout {CREDENTIALS_CREATE_TIMEOUT} "
|
||||||
f"issue-secret --wallet {wallet_path} --gate-public-key={gate_public_key} "
|
f"issue-secret --wallet {wallet_path} --gate-public-key={gate_public_key} "
|
||||||
|
|
|
@ -5,20 +5,14 @@ from typing import Dict, List, Optional
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from common import (
|
import yaml
|
||||||
ASSETS_DIR,
|
from common import ASSETS_DIR, IR_WALLET_PATH, STORAGE_WALLET_PATH, WALLET_CONFIG, WALLET_PASS
|
||||||
IR_WALLET_CONFIG,
|
|
||||||
IR_WALLET_PATH,
|
|
||||||
STORAGE_WALLET_CONFIG,
|
|
||||||
STORAGE_WALLET_PATH,
|
|
||||||
WALLET_CONFIG,
|
|
||||||
WALLET_PASS,
|
|
||||||
)
|
|
||||||
from file_helper import generate_file
|
from file_helper import generate_file
|
||||||
from neofs_testlib.utils.wallet import init_wallet
|
from neofs_testlib.utils.wallet import init_wallet
|
||||||
from python_keywords.acl import EACLRole
|
from python_keywords.acl import EACLRole
|
||||||
from python_keywords.container import create_container
|
from python_keywords.container import create_container
|
||||||
from python_keywords.neofs_verbs import put_object
|
from python_keywords.neofs_verbs import put_object
|
||||||
|
from utility import create_wallet_config
|
||||||
from wellknown_acl import PUBLIC_ACL
|
from wellknown_acl import PUBLIC_ACL
|
||||||
|
|
||||||
OBJECT_COUNT = 5
|
OBJECT_COUNT = 5
|
||||||
|
@ -42,13 +36,16 @@ class Wallets:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def wallets(prepare_wallet_and_deposit):
|
def wallets(prepare_wallet_and_deposit, hosting):
|
||||||
other_wallets_paths = [
|
other_wallets_paths = [
|
||||||
os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") for _ in range(2)
|
os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json") for _ in range(2)
|
||||||
]
|
]
|
||||||
for other_wallet_path in other_wallets_paths:
|
for other_wallet_path in other_wallets_paths:
|
||||||
init_wallet(other_wallet_path, WALLET_PASS)
|
init_wallet(other_wallet_path, WALLET_PASS)
|
||||||
|
|
||||||
|
ir_wallet_config = create_wallet_config(hosting, "ir01")
|
||||||
|
storage_wallet_config = create_wallet_config(hosting, "s01")
|
||||||
|
|
||||||
yield Wallets(
|
yield Wallets(
|
||||||
wallets={
|
wallets={
|
||||||
EACLRole.USER: [
|
EACLRole.USER: [
|
||||||
|
@ -59,8 +56,8 @@ def wallets(prepare_wallet_and_deposit):
|
||||||
for other_wallet_path in other_wallets_paths
|
for other_wallet_path in other_wallets_paths
|
||||||
],
|
],
|
||||||
EACLRole.SYSTEM: [
|
EACLRole.SYSTEM: [
|
||||||
Wallet(wallet_path=IR_WALLET_PATH, config_path=IR_WALLET_CONFIG),
|
Wallet(wallet_path=IR_WALLET_PATH, config_path=ir_wallet_config),
|
||||||
Wallet(wallet_path=STORAGE_WALLET_PATH, config_path=STORAGE_WALLET_CONFIG),
|
Wallet(wallet_path=STORAGE_WALLET_PATH, config_path=storage_wallet_config),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
import logging
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
|
import yaml
|
||||||
from common import (
|
from common import (
|
||||||
ASSETS_DIR,
|
ASSETS_DIR,
|
||||||
COMPLEX_OBJ_SIZE,
|
COMPLEX_OBJ_SIZE,
|
||||||
FREE_STORAGE,
|
FREE_STORAGE,
|
||||||
IR_WALLET_CONFIG,
|
|
||||||
IR_WALLET_PASS,
|
|
||||||
IR_WALLET_PATH,
|
IR_WALLET_PATH,
|
||||||
SIMPLE_OBJ_SIZE,
|
SIMPLE_OBJ_SIZE,
|
||||||
WALLET_PASS,
|
WALLET_PASS,
|
||||||
|
@ -18,6 +17,7 @@ from common import (
|
||||||
from epoch import tick_epoch
|
from epoch import tick_epoch
|
||||||
from file_helper import generate_file
|
from file_helper import generate_file
|
||||||
from grpc_responses import OBJECT_ACCESS_DENIED, OBJECT_NOT_FOUND
|
from grpc_responses import OBJECT_ACCESS_DENIED, OBJECT_NOT_FOUND
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from neofs_testlib.utils.wallet import init_wallet
|
from neofs_testlib.utils.wallet import init_wallet
|
||||||
from python_keywords.acl import (
|
from python_keywords.acl import (
|
||||||
|
@ -40,6 +40,7 @@ from python_keywords.storage_group import (
|
||||||
verify_get_storage_group,
|
verify_get_storage_group,
|
||||||
verify_list_storage_group,
|
verify_list_storage_group,
|
||||||
)
|
)
|
||||||
|
from utility import get_wallet_password
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
deposit = 30
|
deposit = 30
|
||||||
|
@ -73,16 +74,15 @@ class TestStorageGroup:
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group in Private Container")
|
@allure.title("Test Storage Group in Private Container")
|
||||||
def test_storagegroup_basic_private_container(self, client_shell, object_size):
|
def test_storagegroup_basic_private_container(self, client_shell, object_size, hosting):
|
||||||
cid = create_container(self.main_wallet, shell=client_shell)
|
cid = create_container(self.main_wallet, shell=client_shell)
|
||||||
file_path = generate_file(object_size)
|
file_path = generate_file(object_size)
|
||||||
|
password = get_wallet_password(hosting=hosting, service_name="ir01")
|
||||||
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
||||||
objects = [oid]
|
objects = [oid]
|
||||||
storage_group = put_storagegroup(
|
storage_group = put_storagegroup(
|
||||||
shell=client_shell,
|
shell=client_shell, wallet=self.main_wallet, cid=cid, objects=objects
|
||||||
wallet=self.main_wallet,
|
)
|
||||||
cid=cid,
|
|
||||||
objects=objects)
|
|
||||||
|
|
||||||
self.expect_success_for_storagegroup_operations(
|
self.expect_success_for_storagegroup_operations(
|
||||||
shell=client_shell,
|
shell=client_shell,
|
||||||
|
@ -104,10 +104,11 @@ class TestStorageGroup:
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
hosting=hosting,
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group in Public Container")
|
@allure.title("Test Storage Group in Public Container")
|
||||||
def test_storagegroup_basic_public_container(self, client_shell, object_size):
|
def test_storagegroup_basic_public_container(self, client_shell, object_size, hosting):
|
||||||
cid = create_container(self.main_wallet, basic_acl="public-read-write", shell=client_shell)
|
cid = create_container(self.main_wallet, basic_acl="public-read-write", shell=client_shell)
|
||||||
file_path = generate_file(object_size)
|
file_path = generate_file(object_size)
|
||||||
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
||||||
|
@ -132,10 +133,11 @@ class TestStorageGroup:
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
hosting=hosting,
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group in Read-Only Container")
|
@allure.title("Test Storage Group in Read-Only Container")
|
||||||
def test_storagegroup_basic_ro_container(self, client_shell, object_size):
|
def test_storagegroup_basic_ro_container(self, client_shell, object_size, hosting):
|
||||||
cid = create_container(self.main_wallet, basic_acl="public-read", shell=client_shell)
|
cid = create_container(self.main_wallet, basic_acl="public-read", shell=client_shell)
|
||||||
file_path = generate_file(object_size)
|
file_path = generate_file(object_size)
|
||||||
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
||||||
|
@ -161,6 +163,7 @@ class TestStorageGroup:
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
hosting=hosting,
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group with Bearer Allow")
|
@allure.title("Test Storage Group with Bearer Allow")
|
||||||
|
@ -211,8 +214,9 @@ class TestStorageGroup:
|
||||||
bearer=bearer_file,
|
bearer=bearer_file,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@pytest.mark.skip
|
||||||
@allure.title("Test to check Storage Group lifetime")
|
@allure.title("Test to check Storage Group lifetime")
|
||||||
def test_storagegroup_lifetime(self, client_shell, object_size):
|
def test_storagegroup_lifetime(self, client_shell, object_size, hosting):
|
||||||
cid = create_container(self.main_wallet, shell=client_shell)
|
cid = create_container(self.main_wallet, shell=client_shell)
|
||||||
file_path = generate_file(object_size)
|
file_path = generate_file(object_size)
|
||||||
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
oid = put_object(self.main_wallet, file_path, cid, shell=client_shell)
|
||||||
|
@ -220,7 +224,7 @@ class TestStorageGroup:
|
||||||
storage_group = put_storagegroup(client_shell, self.main_wallet, cid, objects, lifetime=1)
|
storage_group = put_storagegroup(client_shell, self.main_wallet, cid, objects, lifetime=1)
|
||||||
with allure.step("Tick two epochs"):
|
with allure.step("Tick two epochs"):
|
||||||
for _ in range(2):
|
for _ in range(2):
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||||
get_storagegroup(
|
get_storagegroup(
|
||||||
shell=client_shell, wallet=self.main_wallet, cid=cid, gid=storage_group
|
shell=client_shell, wallet=self.main_wallet, cid=cid, gid=storage_group
|
||||||
|
@ -303,33 +307,48 @@ class TestStorageGroup:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@allure.step("Run Storage Group Operations On Systems's Behalf In RO Container")
|
@allure.step("Run Storage Group Operations On Systems's Behalf In RO Container")
|
||||||
def storagegroup_operations_by_system_ro_container(
|
def storagegroup_operations_by_system_ro_container(
|
||||||
shell: Shell, wallet: str, cid: str, obj_list: list, object_size: int
|
shell: Shell, wallet: str, cid: str, obj_list: list, object_size: int, hosting: Hosting
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
In this func we create a Storage Group on Inner Ring's key behalf
|
In this func we create a Storage Group on Inner Ring's key behalf
|
||||||
and include an Object created on behalf of some user. We expect
|
and include an Object created on behalf of some user. We expect
|
||||||
that System key is granted to make all operations except PUT and DELETE.
|
that System key is granted to make all operations except PUT and DELETE.
|
||||||
"""
|
"""
|
||||||
|
password = get_wallet_password(hosting=hosting, service_name="ir01")
|
||||||
|
ir_wallet_config = os.path.join(os.getcwd(), "ir_wallet_config.yml")
|
||||||
|
with open(ir_wallet_config, "w") as file:
|
||||||
|
yaml.dump({"password": password}, file)
|
||||||
if not FREE_STORAGE:
|
if not FREE_STORAGE:
|
||||||
deposit = 30
|
deposit = 30
|
||||||
transfer_gas(
|
transfer_gas(
|
||||||
shell=shell,
|
shell=shell,
|
||||||
amount=deposit + 1,
|
amount=deposit + 1,
|
||||||
wallet_to_path=IR_WALLET_PATH,
|
wallet_to_path=IR_WALLET_PATH,
|
||||||
wallet_to_password=IR_WALLET_PASS,
|
wallet_to_password=password,
|
||||||
)
|
)
|
||||||
deposit_gas(
|
deposit_gas(
|
||||||
shell=shell,
|
shell=shell,
|
||||||
amount=deposit,
|
amount=deposit,
|
||||||
wallet_from_path=IR_WALLET_PATH,
|
wallet_from_path=IR_WALLET_PATH,
|
||||||
wallet_from_password=IR_WALLET_PASS,
|
wallet_from_password=password,
|
||||||
)
|
)
|
||||||
storage_group = put_storagegroup(shell, wallet, cid, obj_list)
|
storage_group = put_storagegroup(shell, wallet, cid, obj_list)
|
||||||
with pytest.raises(Exception, match=OBJECT_ACCESS_DENIED):
|
with pytest.raises(Exception, match=OBJECT_ACCESS_DENIED):
|
||||||
put_storagegroup(shell, IR_WALLET_PATH, cid, obj_list, wallet_config=IR_WALLET_CONFIG)
|
put_storagegroup(
|
||||||
|
shell=shell,
|
||||||
|
wallet=IR_WALLET_PATH,
|
||||||
|
cid=cid,
|
||||||
|
objects=obj_list,
|
||||||
|
wallet_config=ir_wallet_config,
|
||||||
|
)
|
||||||
verify_list_storage_group(
|
verify_list_storage_group(
|
||||||
IR_WALLET_PATH, cid, storage_group, wallet_config=IR_WALLET_CONFIG
|
shell=shell,
|
||||||
|
wallet=IR_WALLET_PATH,
|
||||||
|
cid=cid,
|
||||||
|
gid=storage_group,
|
||||||
|
wallet_config=ir_wallet_config,
|
||||||
)
|
)
|
||||||
|
|
||||||
verify_get_storage_group(
|
verify_get_storage_group(
|
||||||
shell=shell,
|
shell=shell,
|
||||||
wallet=IR_WALLET_PATH,
|
wallet=IR_WALLET_PATH,
|
||||||
|
@ -337,7 +356,7 @@ class TestStorageGroup:
|
||||||
gid=storage_group,
|
gid=storage_group,
|
||||||
obj_list=obj_list,
|
obj_list=obj_list,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
wallet_config=IR_WALLET_CONFIG,
|
wallet_config=ir_wallet_config,
|
||||||
)
|
)
|
||||||
with pytest.raises(Exception, match=OBJECT_ACCESS_DENIED):
|
with pytest.raises(Exception, match=OBJECT_ACCESS_DENIED):
|
||||||
delete_storagegroup(
|
delete_storagegroup(
|
||||||
|
@ -345,5 +364,5 @@ class TestStorageGroup:
|
||||||
wallet=IR_WALLET_PATH,
|
wallet=IR_WALLET_PATH,
|
||||||
cid=cid,
|
cid=cid,
|
||||||
gid=storage_group,
|
gid=storage_group,
|
||||||
wallet_config=IR_WALLET_CONFIG,
|
wallet_config=ir_wallet_config,
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,6 +29,7 @@ from python_keywords.object_access import (
|
||||||
can_put_object,
|
can_put_object,
|
||||||
can_search_object,
|
can_search_object,
|
||||||
)
|
)
|
||||||
|
from utility import create_wallet_config
|
||||||
from wellknown_acl import PUBLIC_ACL
|
from wellknown_acl import PUBLIC_ACL
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,13 +231,21 @@ class TestEACLContainer:
|
||||||
drop_object(hosting, node_name=[*NEOFS_NETMAP_DICT][0], cid=cid, oid=oid)
|
drop_object(hosting, node_name=[*NEOFS_NETMAP_DICT][0], cid=cid, oid=oid)
|
||||||
|
|
||||||
storage_wallet_path = NEOFS_NETMAP_DICT[[*NEOFS_NETMAP_DICT][0]]["wallet_path"]
|
storage_wallet_path = NEOFS_NETMAP_DICT[[*NEOFS_NETMAP_DICT][0]]["wallet_path"]
|
||||||
|
storage_wallet_conf = create_wallet_config(hosting, [*NEOFS_NETMAP_DICT][0])
|
||||||
with allure.step("Wait for dropped object replicated"):
|
with allure.step("Wait for dropped object replicated"):
|
||||||
wait_object_replication_on_nodes(
|
wait_object_replication_on_nodes(
|
||||||
storage_wallet_path, cid, oid, self.NODE_COUNT, shell=client_shell
|
storage_wallet_path,
|
||||||
|
cid,
|
||||||
|
oid,
|
||||||
|
self.NODE_COUNT,
|
||||||
|
shell=client_shell,
|
||||||
|
wallet_config=storage_wallet_conf,
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Testcase to validate NeoFS system operations with extended ACL")
|
@allure.title("Testcase to validate NeoFS system operations with extended ACL")
|
||||||
def test_extended_actions_system(self, wallets, client_shell, eacl_container_with_objects):
|
def test_extended_actions_system(
|
||||||
|
self, wallets, client_shell, eacl_container_with_objects, hosting
|
||||||
|
):
|
||||||
user_wallet = wallets.get_wallet()
|
user_wallet = wallets.get_wallet()
|
||||||
ir_wallet, storage_wallet = wallets.get_wallets_list(role=EACLRole.SYSTEM)[:2]
|
ir_wallet, storage_wallet = wallets.get_wallets_list(role=EACLRole.SYSTEM)[:2]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -10,16 +11,27 @@ import yaml
|
||||||
from binary_version_helper import get_local_binaries_versions, get_remote_binaries_versions
|
from binary_version_helper import get_local_binaries_versions, get_remote_binaries_versions
|
||||||
from common import ASSETS_DIR, FREE_STORAGE, HOSTING_CONFIG_FILE, NEOFS_NETMAP_DICT, WALLET_PASS
|
from common import ASSETS_DIR, FREE_STORAGE, HOSTING_CONFIG_FILE, NEOFS_NETMAP_DICT, WALLET_PASS
|
||||||
from env_properties import save_env_properties
|
from env_properties import save_env_properties
|
||||||
|
from file_helper import sanitize_for_file_name
|
||||||
from neofs_testlib.hosting import Hosting
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.reporter import AllureHandler, get_reporter
|
from neofs_testlib.reporter import AllureHandler, get_reporter
|
||||||
from neofs_testlib.shell import LocalShell, Shell
|
from neofs_testlib.shell import LocalShell, Shell
|
||||||
from neofs_testlib.utils.wallet import init_wallet
|
from neofs_testlib.utils.wallet import init_wallet
|
||||||
from payment_neogo import deposit_gas, transfer_gas
|
from payment_neogo import deposit_gas, transfer_gas
|
||||||
|
from pytest import FixtureRequest
|
||||||
from python_keywords.node_management import node_healthcheck
|
from python_keywords.node_management import node_healthcheck
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_collection_modifyitems(items):
|
||||||
|
# Make network tests last based on @pytest.mark.node_mgmt
|
||||||
|
def priority(item: pytest.Item) -> int:
|
||||||
|
is_node_mgmt_test = item.get_closest_marker("node_mgmt")
|
||||||
|
return 0 if not is_node_mgmt_test else 1
|
||||||
|
|
||||||
|
items.sort(key=lambda item: priority(item))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def configure_testlib():
|
def configure_testlib():
|
||||||
get_reporter().register_handler(AllureHandler())
|
get_reporter().register_handler(AllureHandler())
|
||||||
|
@ -72,6 +84,24 @@ def prepare_tmp_dir():
|
||||||
shutil.rmtree(full_path)
|
shutil.rmtree(full_path)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
|
@allure.title("Analyze logs")
|
||||||
|
def analyze_logs(prepare_tmp_dir: str, hosting: Hosting, request: FixtureRequest):
|
||||||
|
start_time = datetime.utcnow()
|
||||||
|
yield
|
||||||
|
end_time = datetime.utcnow()
|
||||||
|
|
||||||
|
# Skip tests where we expect failures in logs
|
||||||
|
if request.node.get_closest_marker("no_log_analyze"):
|
||||||
|
with allure.step("Skip analyze logs due to no_log_analyze mark"):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Test name may exceed os NAME_MAX (255 bytes), so we use timestamp instead
|
||||||
|
logs_dir = os.path.join(prepare_tmp_dir, f"logs_{sanitize_for_file_name(str(start_time))}")
|
||||||
|
dump_logs(hosting, logs_dir, start_time, end_time)
|
||||||
|
check_logs(logs_dir)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
@allure.title("Collect logs")
|
@allure.title("Collect logs")
|
||||||
def collect_logs(prepare_tmp_dir, hosting: Hosting):
|
def collect_logs(prepare_tmp_dir, hosting: Hosting):
|
||||||
|
@ -81,15 +111,8 @@ def collect_logs(prepare_tmp_dir, hosting: Hosting):
|
||||||
|
|
||||||
# Dump logs to temp directory (because they might be too large to keep in RAM)
|
# Dump logs to temp directory (because they might be too large to keep in RAM)
|
||||||
logs_dir = os.path.join(prepare_tmp_dir, "logs")
|
logs_dir = os.path.join(prepare_tmp_dir, "logs")
|
||||||
os.makedirs(logs_dir)
|
dump_logs(hosting, logs_dir, start_time, end_time)
|
||||||
|
attach_logs(logs_dir)
|
||||||
for host in hosting.hosts:
|
|
||||||
host.dump_logs(logs_dir, since=start_time, until=end_time)
|
|
||||||
|
|
||||||
# Zip all files and attach to Allure because it is more convenient to download a single
|
|
||||||
# zip with all logs rather than mess with individual logs files per service or node
|
|
||||||
logs_zip_file_path = shutil.make_archive(logs_dir, "zip", logs_dir)
|
|
||||||
allure.attach.file(logs_zip_file_path, name="logs.zip", extension="zip")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
|
@ -108,6 +131,10 @@ def run_health_check(collect_logs, hosting: Hosting):
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@allure.title("Prepare wallet and deposit")
|
@allure.title("Prepare wallet and deposit")
|
||||||
def prepare_wallet_and_deposit(client_shell, prepare_tmp_dir):
|
def prepare_wallet_and_deposit(client_shell, prepare_tmp_dir):
|
||||||
|
return create_wallet_with_gas(client_shell, prepare_tmp_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def create_wallet_with_gas(client_shell, prepare_tmp_dir):
|
||||||
wallet_path = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json")
|
wallet_path = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json")
|
||||||
init_wallet(wallet_path, WALLET_PASS)
|
init_wallet(wallet_path, WALLET_PASS)
|
||||||
allure.attach.file(wallet_path, os.path.basename(wallet_path), allure.attachment_type.JSON)
|
allure.attach.file(wallet_path, os.path.basename(wallet_path), allure.attachment_type.JSON)
|
||||||
|
@ -128,3 +155,39 @@ def prepare_wallet_and_deposit(client_shell, prepare_tmp_dir):
|
||||||
)
|
)
|
||||||
|
|
||||||
return wallet_path
|
return wallet_path
|
||||||
|
|
||||||
|
|
||||||
|
def check_logs(logs_dir: str):
|
||||||
|
problem_pattern = r"\Wpanic\W|\Woom\W"
|
||||||
|
|
||||||
|
log_file_paths = []
|
||||||
|
for directory_path, _, file_names in os.walk(logs_dir):
|
||||||
|
log_file_paths += [
|
||||||
|
os.path.join(directory_path, file_name)
|
||||||
|
for file_name in file_names
|
||||||
|
if re.match(r"\.(txt|log)", os.path.splitext(file_name)[-1], flags=re.IGNORECASE)
|
||||||
|
]
|
||||||
|
|
||||||
|
logs_with_problem = []
|
||||||
|
for file_path in log_file_paths:
|
||||||
|
with open(file_path, "r") as log_file:
|
||||||
|
if re.search(problem_pattern, log_file.read(), flags=re.IGNORECASE):
|
||||||
|
attach_logs(logs_dir)
|
||||||
|
logs_with_problem.append(file_path)
|
||||||
|
if logs_with_problem:
|
||||||
|
raise pytest.fail(f"System logs {', '.join(logs_with_problem)} contain critical errors")
|
||||||
|
|
||||||
|
|
||||||
|
def dump_logs(hosting: Hosting, logs_dir: str, since: datetime, until: datetime) -> None:
|
||||||
|
# Dump logs to temp directory (because they might be too large to keep in RAM)
|
||||||
|
os.makedirs(logs_dir)
|
||||||
|
|
||||||
|
for host in hosting.hosts:
|
||||||
|
host.dump_logs(logs_dir, since=since, until=until)
|
||||||
|
|
||||||
|
|
||||||
|
def attach_logs(logs_dir: str) -> None:
|
||||||
|
# Zip all files and attach to Allure because it is more convenient to download a single
|
||||||
|
# zip with all logs rather than mess with individual logs files per service or node
|
||||||
|
logs_zip_file_path = shutil.make_archive(logs_dir, "zip", logs_dir)
|
||||||
|
allure.attach.file(logs_zip_file_path, name="logs.zip", extension="zip")
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from epoch import tick_epoch
|
from epoch import tick_epoch
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from python_keywords.container import (
|
from python_keywords.container import (
|
||||||
create_container,
|
create_container,
|
||||||
delete_container,
|
delete_container,
|
||||||
|
@ -18,7 +19,7 @@ from wellknown_acl import PRIVATE_ACL_F
|
||||||
@pytest.mark.parametrize("name", ["", "test-container"], ids=["No name", "Set particular name"])
|
@pytest.mark.parametrize("name", ["", "test-container"], ids=["No name", "Set particular name"])
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
@pytest.mark.container
|
@pytest.mark.container
|
||||||
def test_container_creation(client_shell, prepare_wallet_and_deposit, name):
|
def test_container_creation(client_shell, prepare_wallet_and_deposit, name, hosting):
|
||||||
scenario_title = f"with name {name}" if name else "without name"
|
scenario_title = f"with name {name}" if name else "without name"
|
||||||
allure.dynamic.title(f"User can create container {scenario_title}")
|
allure.dynamic.title(f"User can create container {scenario_title}")
|
||||||
|
|
||||||
|
@ -58,14 +59,14 @@ def test_container_creation(client_shell, prepare_wallet_and_deposit, name):
|
||||||
|
|
||||||
with allure.step("Delete container and check it was deleted"):
|
with allure.step("Delete container and check it was deleted"):
|
||||||
delete_container(wallet, cid, shell=client_shell)
|
delete_container(wallet, cid, shell=client_shell)
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
wait_for_container_deletion(wallet, cid, shell=client_shell)
|
wait_for_container_deletion(wallet, cid, shell=client_shell)
|
||||||
|
|
||||||
|
|
||||||
@allure.title("Parallel container creation and deletion")
|
@allure.title("Parallel container creation and deletion")
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
@pytest.mark.container
|
@pytest.mark.container
|
||||||
def test_container_creation_deletion_parallel(client_shell, prepare_wallet_and_deposit):
|
def test_container_creation_deletion_parallel(client_shell, prepare_wallet_and_deposit, hosting):
|
||||||
containers_count = 3
|
containers_count = 3
|
||||||
wallet = prepare_wallet_and_deposit
|
wallet = prepare_wallet_and_deposit
|
||||||
placement_rule = "REP 2 IN X CBF 1 SELECT 2 FROM * AS X"
|
placement_rule = "REP 2 IN X CBF 1 SELECT 2 FROM * AS X"
|
||||||
|
@ -92,5 +93,5 @@ def test_container_creation_deletion_parallel(client_shell, prepare_wallet_and_d
|
||||||
with allure.step("Delete containers and check they were deleted"):
|
with allure.step("Delete containers and check they were deleted"):
|
||||||
for cid in cids:
|
for cid in cids:
|
||||||
delete_container(wallet, cid, shell=client_shell)
|
delete_container(wallet, cid, shell=client_shell)
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
wait_for_container_deletion(wallet, cid, shell=client_shell)
|
wait_for_container_deletion(wallet, cid, shell=client_shell)
|
||||||
|
|
|
@ -3,14 +3,12 @@ from enum import Enum
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from common import (
|
from common import (
|
||||||
|
HTTP_GATE_SERVICE_NAME_REGEX,
|
||||||
LOAD_NODE_SSH_PRIVATE_KEY_PATH,
|
LOAD_NODE_SSH_PRIVATE_KEY_PATH,
|
||||||
LOAD_NODE_SSH_USER,
|
LOAD_NODE_SSH_USER,
|
||||||
LOAD_NODES,
|
LOAD_NODES,
|
||||||
STORAGE_NODE_SERVICE_NAME_REGEX,
|
STORAGE_NODE_SERVICE_NAME_REGEX,
|
||||||
HTTP_GATE_SERVICE_NAME_REGEX,
|
|
||||||
)
|
)
|
||||||
from neofs_testlib.hosting import Hosting
|
|
||||||
|
|
||||||
from k6 import LoadParams
|
from k6 import LoadParams
|
||||||
from load import (
|
from load import (
|
||||||
clear_cache_and_data,
|
clear_cache_and_data,
|
||||||
|
@ -18,6 +16,7 @@ from load import (
|
||||||
multi_node_k6_run,
|
multi_node_k6_run,
|
||||||
prepare_k6_instances,
|
prepare_k6_instances,
|
||||||
)
|
)
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
|
|
||||||
|
|
||||||
class LoadTime(Enum):
|
class LoadTime(Enum):
|
||||||
|
|
|
@ -11,7 +11,6 @@ from common import (
|
||||||
NEOFS_CONTRACT_CACHE_TIMEOUT,
|
NEOFS_CONTRACT_CACHE_TIMEOUT,
|
||||||
NEOFS_NETMAP_DICT,
|
NEOFS_NETMAP_DICT,
|
||||||
STORAGE_RPC_ENDPOINT_1,
|
STORAGE_RPC_ENDPOINT_1,
|
||||||
STORAGE_WALLET_PASS,
|
|
||||||
)
|
)
|
||||||
from data_formatters import get_wallet_public_key
|
from data_formatters import get_wallet_public_key
|
||||||
from epoch import tick_epoch
|
from epoch import tick_epoch
|
||||||
|
@ -38,7 +37,12 @@ from python_keywords.node_management import (
|
||||||
stop_nodes,
|
stop_nodes,
|
||||||
)
|
)
|
||||||
from storage_policy import get_nodes_with_object, get_simple_object_copies
|
from storage_policy import get_nodes_with_object, get_simple_object_copies
|
||||||
from utility import parse_time, placement_policy_from_container, wait_for_gc_pass_on_storage_nodes
|
from utility import (
|
||||||
|
get_wallet_password,
|
||||||
|
parse_time,
|
||||||
|
placement_policy_from_container,
|
||||||
|
wait_for_gc_pass_on_storage_nodes,
|
||||||
|
)
|
||||||
from wellknown_acl import PUBLIC_ACL
|
from wellknown_acl import PUBLIC_ACL
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
@ -109,12 +113,12 @@ def return_nodes(shell: Shell, hosting: Hosting, alive_node: Optional[str] = Non
|
||||||
sleep(parse_time(MORPH_BLOCK_TIME))
|
sleep(parse_time(MORPH_BLOCK_TIME))
|
||||||
for __attempt in range(3):
|
for __attempt in range(3):
|
||||||
try:
|
try:
|
||||||
tick_epoch(shell=shell)
|
tick_epoch(shell=shell, hosting=hosting)
|
||||||
break
|
break
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
sleep(3)
|
sleep(3)
|
||||||
|
|
||||||
check_node_in_map(node, shell=shell, alive_node=alive_node)
|
check_node_in_map(node, shell=shell, hosting=hosting, alive_node=alive_node)
|
||||||
|
|
||||||
|
|
||||||
@allure.title("Add one node to cluster")
|
@allure.title("Add one node to cluster")
|
||||||
|
@ -141,7 +145,7 @@ def test_add_nodes(
|
||||||
)
|
)
|
||||||
alive_node = choice([node for node in NEOFS_NETMAP_DICT if node != additional_node])
|
alive_node = choice([node for node in NEOFS_NETMAP_DICT if node != additional_node])
|
||||||
|
|
||||||
check_node_in_map(additional_node, shell=client_shell, alive_node=alive_node)
|
check_node_in_map(additional_node, shell=client_shell, hosting=hosting, alive_node=alive_node)
|
||||||
|
|
||||||
# Add node to recovery list before messing with it
|
# Add node to recovery list before messing with it
|
||||||
check_nodes.append(additional_node)
|
check_nodes.append(additional_node)
|
||||||
|
@ -197,10 +201,11 @@ def test_nodes_management(prepare_tmp_dir, client_shell, hosting: Hosting):
|
||||||
|
|
||||||
# Calculate public key that identifies node in netmap
|
# Calculate public key that identifies node in netmap
|
||||||
random_node_wallet_path = NEOFS_NETMAP_DICT[random_node]["wallet_path"]
|
random_node_wallet_path = NEOFS_NETMAP_DICT[random_node]["wallet_path"]
|
||||||
random_node_netmap_key = get_wallet_public_key(random_node_wallet_path, STORAGE_WALLET_PASS)
|
node_wallet_password = get_wallet_password(hosting=hosting, service_name=random_node)
|
||||||
|
random_node_netmap_key = get_wallet_public_key(random_node_wallet_path, node_wallet_password)
|
||||||
|
|
||||||
with allure.step("Check node {random_node} is in netmap"):
|
with allure.step("Check node {random_node} is in netmap"):
|
||||||
snapshot = get_netmap_snapshot(node_name=alive_node, shell=client_shell)
|
snapshot = get_netmap_snapshot(node_name=alive_node, shell=client_shell, hosting=hosting)
|
||||||
assert random_node_netmap_key in snapshot, f"Expected node {random_node} in netmap"
|
assert random_node_netmap_key in snapshot, f"Expected node {random_node} in netmap"
|
||||||
|
|
||||||
with allure.step("Run health check for all storage nodes"):
|
with allure.step("Run health check for all storage nodes"):
|
||||||
|
@ -212,24 +217,24 @@ def test_nodes_management(prepare_tmp_dir, client_shell, hosting: Hosting):
|
||||||
node_set_status(hosting, random_node, status="offline")
|
node_set_status(hosting, random_node, status="offline")
|
||||||
|
|
||||||
sleep(parse_time(MORPH_BLOCK_TIME))
|
sleep(parse_time(MORPH_BLOCK_TIME))
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
with allure.step(f"Check node {random_node} went to offline"):
|
with allure.step(f"Check node {random_node} went to offline"):
|
||||||
health_check = node_healthcheck(hosting, random_node)
|
health_check = node_healthcheck(hosting, random_node)
|
||||||
assert health_check.health_status == "READY" and health_check.network_status == "OFFLINE"
|
assert health_check.health_status == "READY" and health_check.network_status == "OFFLINE"
|
||||||
snapshot = get_netmap_snapshot(node_name=alive_node, shell=client_shell)
|
snapshot = get_netmap_snapshot(node_name=alive_node, shell=client_shell, hosting=hosting)
|
||||||
assert random_node_netmap_key not in snapshot, f"Expected node {random_node} not in netmap"
|
assert random_node_netmap_key not in snapshot, f"Expected node {random_node} not in netmap"
|
||||||
|
|
||||||
with allure.step(f"Check node {random_node} went to online"):
|
with allure.step(f"Check node {random_node} went to online"):
|
||||||
node_set_status(hosting, random_node, status="online")
|
node_set_status(hosting, random_node, status="online")
|
||||||
|
|
||||||
sleep(parse_time(MORPH_BLOCK_TIME))
|
sleep(parse_time(MORPH_BLOCK_TIME))
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
with allure.step(f"Check node {random_node} went to online"):
|
with allure.step(f"Check node {random_node} went to online"):
|
||||||
health_check = node_healthcheck(hosting, random_node)
|
health_check = node_healthcheck(hosting, random_node)
|
||||||
assert health_check.health_status == "READY" and health_check.network_status == "ONLINE"
|
assert health_check.health_status == "READY" and health_check.network_status == "ONLINE"
|
||||||
snapshot = get_netmap_snapshot(node_name=alive_node, shell=client_shell)
|
snapshot = get_netmap_snapshot(node_name=alive_node, shell=client_shell, hosting=hosting)
|
||||||
assert random_node_netmap_key in snapshot, f"Expected node {random_node} in netmap"
|
assert random_node_netmap_key in snapshot, f"Expected node {random_node} in netmap"
|
||||||
|
|
||||||
|
|
||||||
|
@ -349,7 +354,7 @@ def test_placement_policy_negative(
|
||||||
@pytest.mark.node_mgmt
|
@pytest.mark.node_mgmt
|
||||||
@allure.title("NeoFS object replication on node failover")
|
@allure.title("NeoFS object replication on node failover")
|
||||||
def test_replication(
|
def test_replication(
|
||||||
prepare_wallet_and_deposit, client_shell: Shell, after_run_start_all_nodes, hosting: Hosting
|
prepare_wallet_and_deposit, client_shell: Shell, after_run_start_all_nodes, hosting: Hosting
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Test checks object replication on storage not failover and come back.
|
Test checks object replication on storage not failover and come back.
|
||||||
|
@ -372,7 +377,7 @@ def test_replication(
|
||||||
wait_for_expected_object_copies(client_shell, wallet, cid, oid)
|
wait_for_expected_object_copies(client_shell, wallet, cid, oid)
|
||||||
|
|
||||||
start_nodes(hosting, stopped_nodes)
|
start_nodes(hosting, stopped_nodes)
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
for node_name in node_names:
|
for node_name in node_names:
|
||||||
wait_for_node_go_online(hosting, node_name)
|
wait_for_node_go_online(hosting, node_name)
|
||||||
|
@ -508,13 +513,13 @@ def wait_for_node_to_be_ready(hosting: Hosting, node_name: str) -> None:
|
||||||
|
|
||||||
@allure.step("Wait for {expected_copies} object copies in the wallet")
|
@allure.step("Wait for {expected_copies} object copies in the wallet")
|
||||||
def wait_for_expected_object_copies(
|
def wait_for_expected_object_copies(
|
||||||
shell: Shell, wallet: str, cid: str, oid: str, expected_copies: int = 2
|
shell: Shell, wallet: str, cid: str, oid: str, hosting: Hosting, expected_copies: int = 2
|
||||||
) -> None:
|
) -> None:
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
copies = get_simple_object_copies(wallet, cid, oid)
|
copies = get_simple_object_copies(wallet, cid, oid)
|
||||||
if copies == expected_copies:
|
if copies == expected_copies:
|
||||||
break
|
break
|
||||||
tick_epoch(shell=shell)
|
tick_epoch(shell=shell, hosting=hosting)
|
||||||
sleep(parse_time(NEOFS_CONTRACT_CACHE_TIMEOUT))
|
sleep(parse_time(NEOFS_CONTRACT_CACHE_TIMEOUT))
|
||||||
else:
|
else:
|
||||||
raise AssertionError(f"There are no {expected_copies} copies during time")
|
raise AssertionError(f"There are no {expected_copies} copies during time")
|
||||||
|
|
|
@ -11,6 +11,7 @@ from container import create_container
|
||||||
from epoch import tick_epoch
|
from epoch import tick_epoch
|
||||||
from file_helper import generate_file, get_file_content, get_file_hash
|
from file_helper import generate_file, get_file_content, get_file_hash
|
||||||
from grpc_responses import OBJECT_ALREADY_REMOVED, OUT_OF_RANGE, error_matches_status
|
from grpc_responses import OBJECT_ALREADY_REMOVED, OUT_OF_RANGE, error_matches_status
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from pytest import FixtureRequest
|
from pytest import FixtureRequest
|
||||||
from python_keywords.neofs_verbs import (
|
from python_keywords.neofs_verbs import (
|
||||||
|
@ -94,7 +95,7 @@ def generate_ranges(file_size: int, max_object_size: int) -> list[(int, int)]:
|
||||||
return file_ranges_to_test
|
return file_ranges_to_test
|
||||||
|
|
||||||
|
|
||||||
def delete_objects(storage_objects: list, client_shell: Shell) -> None:
|
def delete_objects(storage_objects: list, client_shell: Shell, hosting: Hosting) -> None:
|
||||||
with allure.step("Delete objects"):
|
with allure.step("Delete objects"):
|
||||||
for storage_object in storage_objects:
|
for storage_object in storage_objects:
|
||||||
storage_object.tombstone = delete_object(
|
storage_object.tombstone = delete_object(
|
||||||
|
@ -108,7 +109,7 @@ def delete_objects(storage_objects: list, client_shell: Shell) -> None:
|
||||||
shell=client_shell,
|
shell=client_shell,
|
||||||
)
|
)
|
||||||
|
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
sleep(CLEANUP_TIMEOUT)
|
sleep(CLEANUP_TIMEOUT)
|
||||||
|
|
||||||
with allure.step("Get objects and check errors"):
|
with allure.step("Get objects and check errors"):
|
||||||
|
@ -129,7 +130,7 @@ def delete_objects(storage_objects: list, client_shell: Shell) -> None:
|
||||||
scope="session",
|
scope="session",
|
||||||
)
|
)
|
||||||
def storage_objects(
|
def storage_objects(
|
||||||
prepare_wallet_and_deposit: str, client_shell: Shell, request: FixtureRequest
|
prepare_wallet_and_deposit: str, client_shell: Shell, request: FixtureRequest, hosting: Hosting
|
||||||
) -> list[StorageObjectInfo]:
|
) -> list[StorageObjectInfo]:
|
||||||
wallet = prepare_wallet_and_deposit
|
wallet = prepare_wallet_and_deposit
|
||||||
# Separate containers for complex/simple objects to avoid side-effects
|
# Separate containers for complex/simple objects to avoid side-effects
|
||||||
|
@ -163,7 +164,7 @@ def storage_objects(
|
||||||
yield storage_objects
|
yield storage_objects
|
||||||
|
|
||||||
# Teardown after all tests done with current param
|
# Teardown after all tests done with current param
|
||||||
delete_objects(storage_objects, client_shell)
|
delete_objects(storage_objects, client_shell, hosting)
|
||||||
|
|
||||||
|
|
||||||
@allure.title("Validate object storage policy by native API")
|
@allure.title("Validate object storage policy by native API")
|
||||||
|
@ -290,7 +291,11 @@ def test_search_object_api(
|
||||||
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
||||||
)
|
)
|
||||||
def test_object_search_should_return_tombstone_items(
|
def test_object_search_should_return_tombstone_items(
|
||||||
prepare_wallet_and_deposit: str, client_shell: Shell, request: FixtureRequest, object_size: int
|
prepare_wallet_and_deposit: str,
|
||||||
|
client_shell: Shell,
|
||||||
|
request: FixtureRequest,
|
||||||
|
object_size: int,
|
||||||
|
hosting: Hosting,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Validate object search with removed items
|
Validate object search with removed items
|
||||||
|
@ -321,7 +326,7 @@ def test_object_search_should_return_tombstone_items(
|
||||||
assert result == [storage_object.oid]
|
assert result == [storage_object.oid]
|
||||||
|
|
||||||
with allure.step("Delete file"):
|
with allure.step("Delete file"):
|
||||||
delete_objects([storage_object], client_shell)
|
delete_objects([storage_object], client_shell, hosting)
|
||||||
|
|
||||||
with allure.step("Search deleted object with --root"):
|
with allure.step("Search deleted object with --root"):
|
||||||
# Root Search object should return nothing
|
# Root Search object should return nothing
|
||||||
|
|
|
@ -7,6 +7,7 @@ from container import create_container
|
||||||
from epoch import get_epoch, tick_epoch
|
from epoch import get_epoch, tick_epoch
|
||||||
from file_helper import generate_file, get_file_hash
|
from file_helper import generate_file, get_file_hash
|
||||||
from grpc_responses import OBJECT_NOT_FOUND
|
from grpc_responses import OBJECT_NOT_FOUND
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from pytest import FixtureRequest
|
from pytest import FixtureRequest
|
||||||
from python_keywords.neofs_verbs import get_object, put_object
|
from python_keywords.neofs_verbs import get_object, put_object
|
||||||
|
@ -22,7 +23,11 @@ logger = logging.getLogger("NeoLogger")
|
||||||
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
||||||
)
|
)
|
||||||
def test_object_api_lifetime(
|
def test_object_api_lifetime(
|
||||||
prepare_wallet_and_deposit: str, client_shell: Shell, request: FixtureRequest, object_size: int
|
prepare_wallet_and_deposit: str,
|
||||||
|
client_shell: Shell,
|
||||||
|
request: FixtureRequest,
|
||||||
|
object_size: int,
|
||||||
|
hosting: Hosting,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Test object deleted after expiration epoch.
|
Test object deleted after expiration epoch.
|
||||||
|
@ -42,7 +47,7 @@ def test_object_api_lifetime(
|
||||||
|
|
||||||
with allure.step("Tick two epochs"):
|
with allure.step("Tick two epochs"):
|
||||||
for _ in range(2):
|
for _ in range(2):
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
||||||
wait_for_gc_pass_on_storage_nodes()
|
wait_for_gc_pass_on_storage_nodes()
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import uuid
|
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
import yaml
|
import yaml
|
||||||
from common import ASSETS_DIR, FREE_STORAGE, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG, WALLET_PASS
|
from common import FREE_STORAGE, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG, WALLET_PASS
|
||||||
from neofs_testlib.cli import NeofsCli
|
from neofs_testlib.cli import NeofsCli
|
||||||
from neofs_testlib.utils.wallet import get_last_address_from_wallet, init_wallet
|
from neofs_testlib.shell import CommandResult, Shell
|
||||||
|
from neofs_testlib.utils.wallet import get_last_address_from_wallet
|
||||||
|
|
||||||
|
from testsuites.conftest import create_wallet_with_gas
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
DEPOSIT_AMOUNT = 30
|
DEPOSIT_AMOUNT = 30
|
||||||
|
@ -16,51 +18,30 @@ DEPOSIT_AMOUNT = 30
|
||||||
@pytest.mark.payments
|
@pytest.mark.payments
|
||||||
@pytest.mark.skipif(FREE_STORAGE, reason="Test only works on public network with paid storage")
|
@pytest.mark.skipif(FREE_STORAGE, reason="Test only works on public network with paid storage")
|
||||||
class TestBalanceAccounting:
|
class TestBalanceAccounting:
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(scope="class")
|
||||||
def prepare_two_wallets(self, prepare_wallet_and_deposit):
|
def main_wallet(self, client_shell, prepare_tmp_dir) -> str:
|
||||||
self.user_wallet = prepare_wallet_and_deposit
|
return create_wallet_with_gas(client_shell=client_shell, prepare_tmp_dir=prepare_tmp_dir)
|
||||||
self.address = get_last_address_from_wallet(self.user_wallet, WALLET_PASS)
|
|
||||||
another_wallet = os.path.join(os.getcwd(), ASSETS_DIR, f"{str(uuid.uuid4())}.json")
|
|
||||||
init_wallet(another_wallet, WALLET_PASS)
|
|
||||||
self.another_address = get_last_address_from_wallet(another_wallet, WALLET_PASS)
|
|
||||||
|
|
||||||
@allure.title("Test balance request with wallet and address")
|
@pytest.fixture(scope="class")
|
||||||
def test_balance_wallet_address(self, client_shell):
|
def other_wallet(self, client_shell, prepare_tmp_dir) -> str:
|
||||||
cli = NeofsCli(client_shell, NEOFS_CLI_EXEC, WALLET_CONFIG)
|
return create_wallet_with_gas(client_shell=client_shell, prepare_tmp_dir=prepare_tmp_dir)
|
||||||
result = cli.accounting.balance(
|
|
||||||
wallet=self.user_wallet,
|
|
||||||
rpc_endpoint=NEOFS_ENDPOINT,
|
|
||||||
address=self.address,
|
|
||||||
)
|
|
||||||
assert int(result.stdout.rstrip()) == DEPOSIT_AMOUNT
|
|
||||||
|
|
||||||
@allure.title("Test balance request with wallet only")
|
@pytest.fixture(scope="class")
|
||||||
def test_balance_wallet(self, client_shell):
|
def cli(self, client_shell: Shell) -> NeofsCli:
|
||||||
cli = NeofsCli(client_shell, NEOFS_CLI_EXEC, WALLET_CONFIG)
|
return NeofsCli(client_shell, NEOFS_CLI_EXEC, WALLET_CONFIG)
|
||||||
result = cli.accounting.balance(wallet=self.user_wallet, rpc_endpoint=NEOFS_ENDPOINT)
|
|
||||||
assert int(result.stdout.rstrip()) == DEPOSIT_AMOUNT
|
|
||||||
|
|
||||||
@allure.title("Test balance request with wallet and wrong address")
|
@allure.step("Check deposit amount")
|
||||||
def test_balance_wrong_address(self, client_shell):
|
def check_amount(self, result: CommandResult) -> None:
|
||||||
with pytest.raises(Exception, match="address option must be specified and valid"):
|
amount_str = result.stdout.rstrip()
|
||||||
cli = NeofsCli(client_shell, NEOFS_CLI_EXEC, WALLET_CONFIG)
|
|
||||||
cli.accounting.balance(
|
try:
|
||||||
wallet=self.user_wallet,
|
amount = int(amount_str)
|
||||||
rpc_endpoint=NEOFS_ENDPOINT,
|
except Exception as ex:
|
||||||
address=self.another_address,
|
pytest.fail(
|
||||||
|
f"Amount parse error, should be parsable as int({DEPOSIT_AMOUNT}), but given {amount_str}: {ex}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test balance request with config file")
|
assert amount == DEPOSIT_AMOUNT
|
||||||
def test_balance_api(self, prepare_tmp_dir, client_shell):
|
|
||||||
config_file = self.write_api_config(
|
|
||||||
config_dir=prepare_tmp_dir, endpoint=NEOFS_ENDPOINT, wallet=self.user_wallet
|
|
||||||
)
|
|
||||||
logger.info(f"Config with API endpoint: {config_file}")
|
|
||||||
|
|
||||||
cli = NeofsCli(client_shell, NEOFS_CLI_EXEC, config_file=config_file)
|
|
||||||
result = cli.accounting.balance()
|
|
||||||
|
|
||||||
assert int(result.stdout.rstrip()) == DEPOSIT_AMOUNT
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@allure.step("Write config with API endpoint")
|
@allure.step("Write config with API endpoint")
|
||||||
|
@ -76,3 +57,39 @@ class TestBalanceAccounting:
|
||||||
with open(api_config_file, "w") as file:
|
with open(api_config_file, "w") as file:
|
||||||
yaml.dump(api_config, file)
|
yaml.dump(api_config, file)
|
||||||
return api_config_file
|
return api_config_file
|
||||||
|
|
||||||
|
@allure.title("Test balance request with wallet and address")
|
||||||
|
def test_balance_wallet_address(self, main_wallet: str, cli: NeofsCli):
|
||||||
|
result = cli.accounting.balance(
|
||||||
|
wallet=main_wallet,
|
||||||
|
rpc_endpoint=NEOFS_ENDPOINT,
|
||||||
|
address=get_last_address_from_wallet(main_wallet, WALLET_PASS),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.check_amount(result)
|
||||||
|
|
||||||
|
@allure.title("Test balance request with wallet only")
|
||||||
|
def test_balance_wallet(self, main_wallet: str, cli: NeofsCli):
|
||||||
|
result = cli.accounting.balance(wallet=main_wallet, rpc_endpoint=NEOFS_ENDPOINT)
|
||||||
|
self.check_amount(result)
|
||||||
|
|
||||||
|
@allure.title("Test balance request with wallet and wrong address")
|
||||||
|
def test_balance_wrong_address(self, main_wallet: str, other_wallet: str, cli: NeofsCli):
|
||||||
|
with pytest.raises(Exception, match="address option must be specified and valid"):
|
||||||
|
cli.accounting.balance(
|
||||||
|
wallet=main_wallet,
|
||||||
|
rpc_endpoint=NEOFS_ENDPOINT,
|
||||||
|
address=get_last_address_from_wallet(other_wallet, WALLET_PASS),
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("Test balance request with config file")
|
||||||
|
def test_balance_api(self, prepare_tmp_dir: str, main_wallet: str, client_shell: Shell):
|
||||||
|
config_file = self.write_api_config(
|
||||||
|
config_dir=prepare_tmp_dir, endpoint=NEOFS_ENDPOINT, wallet=main_wallet
|
||||||
|
)
|
||||||
|
logger.info(f"Config with API endpoint: {config_file}")
|
||||||
|
|
||||||
|
cli = NeofsCli(client_shell, NEOFS_CLI_EXEC, config_file=config_file)
|
||||||
|
result = cli.accounting.balance()
|
||||||
|
|
||||||
|
self.check_amount(result)
|
||||||
|
|
|
@ -66,7 +66,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket)
|
s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket)
|
||||||
|
|
||||||
@allure.title("Test S3 Bucket API")
|
@allure.title("Test S3 Bucket API")
|
||||||
def test_s3_buckets(self, client_shell):
|
def test_s3_buckets(self, client_shell, hosting):
|
||||||
"""
|
"""
|
||||||
Test base S3 Bucket API (Create/List/Head/Delete).
|
Test base S3 Bucket API (Create/List/Head/Delete).
|
||||||
"""
|
"""
|
||||||
|
@ -110,7 +110,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
|
|
||||||
with allure.step(f"Delete empty bucket {bucket_2}"):
|
with allure.step(f"Delete empty bucket {bucket_2}"):
|
||||||
s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket_2)
|
s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket_2)
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
with allure.step(f"Check bucket {bucket_2} deleted"):
|
with allure.step(f"Check bucket {bucket_2} deleted"):
|
||||||
with pytest.raises(Exception, match=r".*Not Found.*"):
|
with pytest.raises(Exception, match=r".*Not Found.*"):
|
||||||
|
@ -126,7 +126,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
|
|
||||||
with allure.step(f"Delete bucket {bucket_1}"):
|
with allure.step(f"Delete bucket {bucket_1}"):
|
||||||
s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket_1)
|
s3_gate_bucket.delete_bucket_s3(self.s3_client, bucket_1)
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
with allure.step(f"Check bucket {bucket_1} deleted"):
|
with allure.step(f"Check bucket {bucket_1} deleted"):
|
||||||
with pytest.raises(Exception, match=r".*Not Found.*"):
|
with pytest.raises(Exception, match=r".*Not Found.*"):
|
||||||
|
|
|
@ -8,9 +8,9 @@ import pytest
|
||||||
from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, FREE_STORAGE, SIMPLE_OBJ_SIZE, WALLET_PASS
|
from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, FREE_STORAGE, SIMPLE_OBJ_SIZE, WALLET_PASS
|
||||||
from data_formatters import get_wallet_public_key
|
from data_formatters import get_wallet_public_key
|
||||||
from file_helper import concat_files, generate_file, generate_file_with_content, get_file_hash
|
from file_helper import concat_files, generate_file, generate_file_with_content, get_file_hash
|
||||||
|
from neofs_testlib.utils.wallet import init_wallet
|
||||||
from python_keywords.payment_neogo import deposit_gas, transfer_gas
|
from python_keywords.payment_neogo import deposit_gas, transfer_gas
|
||||||
from s3_helper import assert_object_lock_mode, check_objects_in_bucket, set_bucket_versioning
|
from s3_helper import assert_object_lock_mode, check_objects_in_bucket, set_bucket_versioning
|
||||||
from neofs_testlib.utils.wallet import init_wallet
|
|
||||||
|
|
||||||
from steps import s3_gate_bucket, s3_gate_object
|
from steps import s3_gate_bucket, s3_gate_object
|
||||||
from steps.aws_cli_client import AwsCliClient
|
from steps.aws_cli_client import AwsCliClient
|
||||||
|
|
|
@ -9,6 +9,7 @@ from common import COMPLEX_OBJ_SIZE
|
||||||
from container import create_container
|
from container import create_container
|
||||||
from epoch import get_epoch, tick_epoch
|
from epoch import get_epoch, tick_epoch
|
||||||
from file_helper import generate_file, get_file_hash
|
from file_helper import generate_file, get_file_hash
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from python_keywords.http_gate import (
|
from python_keywords.http_gate import (
|
||||||
get_via_http_curl,
|
get_via_http_curl,
|
||||||
|
@ -147,7 +148,7 @@ class TestHttpGate:
|
||||||
self.get_object_by_attr_and_verify_hashes(oid, file_path, cid, attributes)
|
self.get_object_by_attr_and_verify_hashes(oid, file_path, cid, attributes)
|
||||||
|
|
||||||
@allure.title("Test Expiration-Epoch in HTTP header")
|
@allure.title("Test Expiration-Epoch in HTTP header")
|
||||||
def test_expiration_epoch_in_http(self, client_shell):
|
def test_expiration_epoch_in_http(self, client_shell, hosting):
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
self.wallet, shell=client_shell, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL
|
self.wallet, shell=client_shell, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL
|
||||||
)
|
)
|
||||||
|
@ -170,7 +171,7 @@ class TestHttpGate:
|
||||||
get_via_http_gate(cid=cid, oid=oid)
|
get_via_http_gate(cid=cid, oid=oid)
|
||||||
|
|
||||||
for expired_objects, not_expired_objects in [(oids[:1], oids[1:]), (oids[:2], oids[2:])]:
|
for expired_objects, not_expired_objects in [(oids[:1], oids[1:]), (oids[:2], oids[2:])]:
|
||||||
tick_epoch(shell=client_shell)
|
tick_epoch(shell=client_shell, hosting=hosting)
|
||||||
|
|
||||||
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
||||||
wait_for_gc_pass_on_storage_nodes()
|
wait_for_gc_pass_on_storage_nodes()
|
||||||
|
|
|
@ -1,8 +1,68 @@
|
||||||
robotframework==4.1.2
|
aiodns==3.0.0
|
||||||
requests==2.25.1
|
aiohttp==3.7.4.post0
|
||||||
pexpect==4.8.0
|
aioresponses==0.7.2
|
||||||
|
allure-pytest==2.9.45
|
||||||
|
allure-python-commons==2.9.45
|
||||||
|
async-timeout==3.0.1
|
||||||
|
asynctest==0.13.0
|
||||||
|
attrs==21.4.0
|
||||||
|
base58==2.1.0
|
||||||
|
bitarray==2.3.4
|
||||||
|
black==22.8.0
|
||||||
boto3==1.16.33
|
boto3==1.16.33
|
||||||
docker==4.4.0
|
|
||||||
botocore==1.19.33
|
botocore==1.19.33
|
||||||
urllib3==1.26.3
|
certifi==2022.5.18
|
||||||
base58==1.0.3
|
cffi==1.15.0
|
||||||
|
chardet==4.0.0
|
||||||
|
charset-normalizer==2.0.12
|
||||||
|
coverage==6.3.3
|
||||||
|
docker==4.4.0
|
||||||
|
docutils==0.17.1
|
||||||
|
Events==0.4
|
||||||
|
flake8==4.0.1
|
||||||
|
idna==3.3
|
||||||
|
iniconfig==1.1.1
|
||||||
|
isort==5.10.1
|
||||||
|
jmespath==0.10.0
|
||||||
|
jsonschema==4.5.1
|
||||||
|
lz4==3.1.3
|
||||||
|
mccabe==0.6.1
|
||||||
|
mmh3==3.0.0
|
||||||
|
multidict==6.0.2
|
||||||
|
mypy==0.950
|
||||||
|
mypy-extensions==0.4.3
|
||||||
|
neo-mamba==0.10.0
|
||||||
|
neo3crypto==0.2.1
|
||||||
|
neo3vm==0.9.0
|
||||||
|
neo3vm-stubs==0.9.0
|
||||||
|
neofs-testlib==0.4.0
|
||||||
|
netaddr==0.8.0
|
||||||
|
orjson==3.6.8
|
||||||
|
packaging==21.3
|
||||||
|
paramiko==2.10.3
|
||||||
|
pexpect==4.8.0
|
||||||
|
pluggy==1.0.0
|
||||||
|
pre-commit==2.20.0
|
||||||
|
ptyprocess==0.7.0
|
||||||
|
py==1.11.0
|
||||||
|
pybiginteger==1.2.6
|
||||||
|
pybiginteger-stubs==1.2.6
|
||||||
|
pycares==4.1.2
|
||||||
|
pycodestyle==2.8.0
|
||||||
|
pycparser==2.21
|
||||||
|
pycryptodome==3.11.0
|
||||||
|
pyflakes==2.4.0
|
||||||
|
pyparsing==3.0.9
|
||||||
|
pyrsistent==0.18.1
|
||||||
|
pytest==7.1.2
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
requests==2.28.0
|
||||||
|
robotframework==4.1.2
|
||||||
|
s3transfer==0.3.7
|
||||||
|
six==1.16.0
|
||||||
|
tenacity==8.0.1
|
||||||
|
tomli==2.0.1
|
||||||
|
typing-extensions==4.2.0
|
||||||
|
urllib3==1.26.9
|
||||||
|
websocket-client==1.3.2
|
||||||
|
yarl==1.7.2
|
||||||
|
|
|
@ -4,7 +4,6 @@ from time import sleep
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
from common import (
|
from common import (
|
||||||
IR_WALLET_PASS,
|
|
||||||
IR_WALLET_PATH,
|
IR_WALLET_PATH,
|
||||||
MAINNET_BLOCK_TIME,
|
MAINNET_BLOCK_TIME,
|
||||||
MORPH_ENDPOINT,
|
MORPH_ENDPOINT,
|
||||||
|
@ -13,10 +12,11 @@ from common import (
|
||||||
NEOGO_EXECUTABLE,
|
NEOGO_EXECUTABLE,
|
||||||
)
|
)
|
||||||
from neofs_testlib.cli import NeofsAdm, NeoGo
|
from neofs_testlib.cli import NeofsAdm, NeoGo
|
||||||
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from neofs_testlib.utils.wallet import get_last_address_from_wallet
|
from neofs_testlib.utils.wallet import get_last_address_from_wallet
|
||||||
from payment_neogo import get_contract_hash
|
from payment_neogo import get_contract_hash
|
||||||
from utility import parse_time
|
from utility import get_wallet_password, parse_time
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ def get_epoch(shell: Shell):
|
||||||
|
|
||||||
|
|
||||||
@allure.step("Tick Epoch")
|
@allure.step("Tick Epoch")
|
||||||
def tick_epoch(shell: Shell):
|
def tick_epoch(shell: Shell, hosting: Hosting):
|
||||||
if NEOFS_ADM_EXEC and NEOFS_ADM_CONFIG_PATH:
|
if NEOFS_ADM_EXEC and NEOFS_ADM_CONFIG_PATH:
|
||||||
# If neofs-adm is available, then we tick epoch with it (to be consistent with UAT tests)
|
# If neofs-adm is available, then we tick epoch with it (to be consistent with UAT tests)
|
||||||
neofsadm = NeofsAdm(
|
neofsadm = NeofsAdm(
|
||||||
|
@ -44,13 +44,13 @@ def tick_epoch(shell: Shell):
|
||||||
|
|
||||||
# Otherwise we tick epoch using transaction
|
# Otherwise we tick epoch using transaction
|
||||||
cur_epoch = get_epoch(shell)
|
cur_epoch = get_epoch(shell)
|
||||||
|
ir_wallet_password = get_wallet_password(hosting, "ir01")
|
||||||
ir_address = get_last_address_from_wallet(IR_WALLET_PATH, IR_WALLET_PASS)
|
ir_address = get_last_address_from_wallet(IR_WALLET_PATH, ir_wallet_password)
|
||||||
|
|
||||||
neogo = NeoGo(shell, neo_go_exec_path=NEOGO_EXECUTABLE)
|
neogo = NeoGo(shell, neo_go_exec_path=NEOGO_EXECUTABLE)
|
||||||
neogo.contract.invokefunction(
|
neogo.contract.invokefunction(
|
||||||
wallet=IR_WALLET_PATH,
|
wallet=IR_WALLET_PATH,
|
||||||
wallet_password=IR_WALLET_PASS,
|
wallet_password=ir_wallet_password,
|
||||||
scripthash=get_contract_hash("netmap.neofs", shell=shell),
|
scripthash=get_contract_hash("netmap.neofs", shell=shell),
|
||||||
method="newEpoch",
|
method="newEpoch",
|
||||||
arguments=f"int:{cur_epoch + 1}",
|
arguments=f"int:{cur_epoch + 1}",
|
||||||
|
|
|
@ -20,12 +20,15 @@ def wait_object_replication_on_nodes(
|
||||||
expected_copies: int,
|
expected_copies: int,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
excluded_nodes: Optional[list[str]] = None,
|
excluded_nodes: Optional[list[str]] = None,
|
||||||
|
wallet_config: Optional[str] = None,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
excluded_nodes = excluded_nodes or []
|
excluded_nodes = excluded_nodes or []
|
||||||
sleep_interval, attempts = 15, 20
|
sleep_interval, attempts = 15, 20
|
||||||
nodes = []
|
nodes = []
|
||||||
for __attempt in range(attempts):
|
for __attempt in range(attempts):
|
||||||
nodes = get_nodes_with_object(wallet, cid, oid, shell=shell, skip_nodes=excluded_nodes)
|
nodes = get_nodes_with_object(
|
||||||
|
wallet, cid, oid, shell=shell, skip_nodes=excluded_nodes, wallet_config=wallet_config
|
||||||
|
)
|
||||||
if len(nodes) >= expected_copies:
|
if len(nodes) >= expected_copies:
|
||||||
return nodes
|
return nodes
|
||||||
sleep(sleep_interval)
|
sleep(sleep_interval)
|
||||||
|
|
|
@ -6,19 +6,13 @@ from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
from common import (
|
from common import MORPH_BLOCK_TIME, NEOFS_CLI_EXEC, NEOFS_NETMAP_DICT
|
||||||
MORPH_BLOCK_TIME,
|
|
||||||
NEOFS_CLI_EXEC,
|
|
||||||
NEOFS_NETMAP_DICT,
|
|
||||||
STORAGE_WALLET_CONFIG,
|
|
||||||
STORAGE_WALLET_PASS,
|
|
||||||
)
|
|
||||||
from data_formatters import get_wallet_public_key
|
from data_formatters import get_wallet_public_key
|
||||||
from epoch import tick_epoch
|
from epoch import tick_epoch
|
||||||
from neofs_testlib.cli import NeofsCli
|
from neofs_testlib.cli import NeofsCli
|
||||||
from neofs_testlib.hosting import Hosting
|
from neofs_testlib.hosting import Hosting
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from utility import parse_time
|
from utility import create_wallet_config, get_wallet_password, parse_time
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
@ -104,7 +98,7 @@ def node_set_status(hosting: Hosting, node_name: str, status: str, retries: int
|
||||||
|
|
||||||
|
|
||||||
@allure.step("Get netmap snapshot")
|
@allure.step("Get netmap snapshot")
|
||||||
def get_netmap_snapshot(node_name: str, shell: Shell) -> str:
|
def get_netmap_snapshot(node_name: str, shell: Shell, hosting: Hosting) -> str:
|
||||||
"""
|
"""
|
||||||
The function returns string representation of netmap snapshot.
|
The function returns string representation of netmap snapshot.
|
||||||
Args:
|
Args:
|
||||||
|
@ -113,7 +107,8 @@ def get_netmap_snapshot(node_name: str, shell: Shell) -> str:
|
||||||
string representation of netmap
|
string representation of netmap
|
||||||
"""
|
"""
|
||||||
node_info = NEOFS_NETMAP_DICT[node_name]
|
node_info = NEOFS_NETMAP_DICT[node_name]
|
||||||
cli = NeofsCli(shell, NEOFS_CLI_EXEC, config_file=STORAGE_WALLET_CONFIG)
|
storage_wallet_config = create_wallet_config(hosting, node_name)
|
||||||
|
cli = NeofsCli(shell, NEOFS_CLI_EXEC, config_file=storage_wallet_config)
|
||||||
return cli.netmap.snapshot(
|
return cli.netmap.snapshot(
|
||||||
rpc_endpoint=node_info["rpc"],
|
rpc_endpoint=node_info["rpc"],
|
||||||
wallet=node_info["wallet_path"],
|
wallet=node_info["wallet_path"],
|
||||||
|
@ -169,14 +164,15 @@ def exclude_node_from_network_map(
|
||||||
hosting: Hosting, node_to_exclude: str, alive_node: str, shell: Shell
|
hosting: Hosting, node_to_exclude: str, alive_node: str, shell: Shell
|
||||||
) -> None:
|
) -> None:
|
||||||
node_wallet_path = NEOFS_NETMAP_DICT[node_to_exclude]["wallet_path"]
|
node_wallet_path = NEOFS_NETMAP_DICT[node_to_exclude]["wallet_path"]
|
||||||
node_netmap_key = get_wallet_public_key(node_wallet_path, STORAGE_WALLET_PASS)
|
node_wallet_password = get_wallet_password(hosting=hosting, service_name=node_to_exclude)
|
||||||
|
node_netmap_key = get_wallet_public_key(node_wallet_path, node_wallet_password)
|
||||||
|
|
||||||
node_set_status(hosting, node_to_exclude, status="offline")
|
node_set_status(hosting, node_to_exclude, status="offline")
|
||||||
|
|
||||||
time.sleep(parse_time(MORPH_BLOCK_TIME))
|
time.sleep(parse_time(MORPH_BLOCK_TIME))
|
||||||
tick_epoch(shell=shell)
|
tick_epoch(shell=shell, hosting=hosting)
|
||||||
|
|
||||||
snapshot = get_netmap_snapshot(node_name=alive_node, shell=shell)
|
snapshot = get_netmap_snapshot(node_name=alive_node, shell=shell, hosting=hosting)
|
||||||
assert (
|
assert (
|
||||||
node_netmap_key not in snapshot
|
node_netmap_key not in snapshot
|
||||||
), f"Expected node with key {node_netmap_key} not in network map"
|
), f"Expected node with key {node_netmap_key} not in network map"
|
||||||
|
@ -188,21 +184,25 @@ def include_node_to_network_map(
|
||||||
) -> None:
|
) -> None:
|
||||||
node_set_status(hosting, node_to_include, status="online")
|
node_set_status(hosting, node_to_include, status="online")
|
||||||
|
|
||||||
time.sleep(parse_time(MORPH_BLOCK_TIME))
|
time.sleep(parse_time(MORPH_BLOCK_TIME) * 2)
|
||||||
tick_epoch(shell=shell)
|
tick_epoch(shell=shell, hosting=hosting)
|
||||||
|
time.sleep(parse_time(MORPH_BLOCK_TIME) * 2)
|
||||||
|
|
||||||
check_node_in_map(node_to_include, shell, alive_node)
|
check_node_in_map(node_to_include, shell, hosting, alive_node)
|
||||||
|
|
||||||
|
|
||||||
@allure.step("Check node {node_name} in network map")
|
@allure.step("Check node {node_name} in network map")
|
||||||
def check_node_in_map(node_name: str, shell: Shell, alive_node: Optional[str] = None) -> None:
|
def check_node_in_map(
|
||||||
|
node_name: str, shell: Shell, hosting: Hosting, alive_node: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
alive_node = alive_node or node_name
|
alive_node = alive_node or node_name
|
||||||
node_wallet_path = NEOFS_NETMAP_DICT[node_name]["wallet_path"]
|
node_wallet_path = NEOFS_NETMAP_DICT[node_name]["wallet_path"]
|
||||||
node_netmap_key = get_wallet_public_key(node_wallet_path, STORAGE_WALLET_PASS)
|
node_wallet_password = get_wallet_password(hosting=hosting, service_name=node_name)
|
||||||
|
node_netmap_key = get_wallet_public_key(node_wallet_path, node_wallet_password)
|
||||||
|
|
||||||
logger.info(f"Node {node_name} netmap key: {node_netmap_key}")
|
logger.info(f"Node {node_name} netmap key: {node_netmap_key}")
|
||||||
|
|
||||||
snapshot = get_netmap_snapshot(node_name=alive_node, shell=shell)
|
snapshot = get_netmap_snapshot(node_name=alive_node, shell=shell, hosting=hosting)
|
||||||
assert node_netmap_key in snapshot, f"Expected node with key {node_netmap_key} in network map"
|
assert node_netmap_key in snapshot, f"Expected node with key {node_netmap_key} in network map"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import uuid
|
||||||
import allure
|
import allure
|
||||||
import json_transformers
|
import json_transformers
|
||||||
from common import ASSETS_DIR, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG
|
from common import ASSETS_DIR, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG
|
||||||
|
from neo3 import wallet
|
||||||
from neofs_testlib.cli import NeofsCli
|
from neofs_testlib.cli import NeofsCli
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from neo3 import wallet
|
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,12 @@ def get_complex_object_copies(wallet: str, cid: str, oid: str, shell: Shell) ->
|
||||||
|
|
||||||
@allure.step("Get Nodes With Object")
|
@allure.step("Get Nodes With Object")
|
||||||
def get_nodes_with_object(
|
def get_nodes_with_object(
|
||||||
wallet: str, cid: str, oid: str, shell: Shell, skip_nodes: Optional[list[str]] = None
|
wallet: str,
|
||||||
|
cid: str,
|
||||||
|
oid: str,
|
||||||
|
shell: Shell,
|
||||||
|
skip_nodes: Optional[list[str]] = None,
|
||||||
|
wallet_config: Optional[str] = None,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""
|
"""
|
||||||
The function returns list of nodes which store
|
The function returns list of nodes which store
|
||||||
|
@ -120,7 +125,13 @@ def get_nodes_with_object(
|
||||||
for node in nodes_to_search:
|
for node in nodes_to_search:
|
||||||
try:
|
try:
|
||||||
res = neofs_verbs.head_object(
|
res = neofs_verbs.head_object(
|
||||||
wallet, cid, oid, shell=shell, endpoint=node, is_direct=True
|
wallet,
|
||||||
|
cid,
|
||||||
|
oid,
|
||||||
|
shell=shell,
|
||||||
|
endpoint=node,
|
||||||
|
is_direct=True,
|
||||||
|
wallet_config=wallet_config,
|
||||||
)
|
)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
logger.info(f"Found object {oid} on node {node}")
|
logger.info(f"Found object {oid} on node {node}")
|
||||||
|
|
|
@ -64,7 +64,7 @@ STORAGE_WALLET_PATH_4 = os.getenv(
|
||||||
"STORAGE_WALLET_PATH_4", os.path.join(DEVENV_PATH, "services", "storage", "wallet04.json")
|
"STORAGE_WALLET_PATH_4", os.path.join(DEVENV_PATH, "services", "storage", "wallet04.json")
|
||||||
)
|
)
|
||||||
STORAGE_WALLET_PATH = STORAGE_WALLET_PATH_1
|
STORAGE_WALLET_PATH = STORAGE_WALLET_PATH_1
|
||||||
STORAGE_WALLET_PASS = os.getenv("STORAGE_WALLET_PASS", "")
|
|
||||||
|
|
||||||
NEOFS_NETMAP_DICT = {
|
NEOFS_NETMAP_DICT = {
|
||||||
"s01": {
|
"s01": {
|
||||||
|
@ -107,7 +107,6 @@ MAINNET_SINGLE_ADDR = os.getenv("MAINNET_SINGLE_ADDR", "NfgHwwTi3wHAS8aFAN243C5v
|
||||||
MAINNET_WALLET_PASS = os.getenv("MAINNET_WALLET_PASS", "one")
|
MAINNET_WALLET_PASS = os.getenv("MAINNET_WALLET_PASS", "one")
|
||||||
|
|
||||||
IR_WALLET_PATH = os.getenv("IR_WALLET_PATH", os.path.join(DEVENV_PATH, "services", "ir", "az.json"))
|
IR_WALLET_PATH = os.getenv("IR_WALLET_PATH", os.path.join(DEVENV_PATH, "services", "ir", "az.json"))
|
||||||
IR_WALLET_PASS = os.getenv("IR_WALLET_PASS", "one")
|
|
||||||
|
|
||||||
S3_GATE_WALLET_PATH = os.getenv(
|
S3_GATE_WALLET_PATH = os.getenv(
|
||||||
"S3_GATE_WALLET_PATH", os.path.join(DEVENV_PATH, "services", "s3_gate", "wallet.json")
|
"S3_GATE_WALLET_PATH", os.path.join(DEVENV_PATH, "services", "s3_gate", "wallet.json")
|
||||||
|
@ -130,15 +129,3 @@ S3_GATE_SERVICE_NAME_REGEX = r"s3-gate\d\d"
|
||||||
WALLET_CONFIG = os.path.join(os.getcwd(), "wallet_config.yml")
|
WALLET_CONFIG = os.path.join(os.getcwd(), "wallet_config.yml")
|
||||||
with open(WALLET_CONFIG, "w") as file:
|
with open(WALLET_CONFIG, "w") as file:
|
||||||
yaml.dump({"password": WALLET_PASS}, file)
|
yaml.dump({"password": WALLET_PASS}, file)
|
||||||
|
|
||||||
STORAGE_WALLET_CONFIG = os.path.join(os.getcwd(), "storage_wallet_config.yml")
|
|
||||||
with open(STORAGE_WALLET_CONFIG, "w") as file:
|
|
||||||
yaml.dump({"password": STORAGE_WALLET_PASS}, file)
|
|
||||||
|
|
||||||
MAINNET_WALLET_CONFIG = os.path.join(os.getcwd(), "mainnet_wallet_config.yml")
|
|
||||||
with open(MAINNET_WALLET_CONFIG, "w") as file:
|
|
||||||
yaml.dump({"password": MAINNET_WALLET_PASS}, file)
|
|
||||||
|
|
||||||
IR_WALLET_CONFIG = os.path.join(os.getcwd(), "ir_wallet_config.yml")
|
|
||||||
with open(IR_WALLET_CONFIG, "w") as file:
|
|
||||||
yaml.dump({"password": IR_WALLET_PASS}, file)
|
|
||||||
|
|
Loading…
Reference in a new issue