Skip to content

Commit cc050f8

Browse files
authored
Merge pull request #63 from nspcc-dev/ezayats/new-dev-env
Update s3-tests to work with new dev env + tests actualization
2 parents 642a544 + 260c39f commit cc050f8

File tree

10 files changed

+362
-252
lines changed

10 files changed

+362
-252
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "neofs-testcases"]
2+
path = neofs-testcases
3+
url = https://github.com/nspcc-dev/neofs-testcases.git

bearer_rules.json

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"records": [
3+
{
4+
"operation": "PUT",
5+
"action": "ALLOW",
6+
"filters": [],
7+
"targets": [
8+
{
9+
"role": "OTHERS",
10+
"keys": []
11+
}
12+
]
13+
},
14+
{
15+
"operation": "GET",
16+
"action": "ALLOW",
17+
"filters": [],
18+
"targets": [
19+
{
20+
"role": "OTHERS",
21+
"keys": []
22+
}
23+
]
24+
},
25+
{
26+
"operation": "DELETE",
27+
"action": "ALLOW",
28+
"filters": [],
29+
"targets": [
30+
{
31+
"role": "OTHERS",
32+
"keys": []
33+
}
34+
]
35+
},
36+
{
37+
"operation": "SEARCH",
38+
"action": "ALLOW",
39+
"filters": [],
40+
"targets": [
41+
{
42+
"role": "OTHERS",
43+
"keys": []
44+
}
45+
]
46+
},
47+
{
48+
"operation": "GETRANGE",
49+
"action": "ALLOW",
50+
"filters": [],
51+
"targets": [
52+
{
53+
"role": "OTHERS",
54+
"keys": []
55+
}
56+
]
57+
},
58+
{
59+
"operation": "GETRANGEHASH",
60+
"action": "ALLOW",
61+
"filters": [],
62+
"targets": [
63+
{
64+
"role": "OTHERS",
65+
"keys": []
66+
}
67+
]
68+
},
69+
{
70+
"operation": "HEAD",
71+
"action": "ALLOW",
72+
"filters": [],
73+
"targets": [
74+
{
75+
"role": "OTHERS",
76+
"keys": []
77+
}
78+
]
79+
}
80+
]
81+
}

conftest.py

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,206 @@
11
import configparser
2+
import json
3+
import logging
4+
import os
5+
import re
6+
import shutil
7+
import sys
8+
import time
9+
from pathlib import Path
210

11+
import allure
12+
import jinja2
13+
import pexpect
314
import pytest
15+
from helpers.common import ASSETS_DIR
16+
from helpers.wallet_helpers import create_wallet
17+
from neofs_testlib.env.env import NeoFSEnv, NodeWallet
18+
from neofs_testlib.reporter import AllureHandler, get_reporter
19+
from neofs_testlib.utils.wallet import (
20+
get_last_address_from_wallet,
21+
get_last_public_key_from_wallet,
22+
)
423

524
from s3tests_boto3.functional import setup
625

26+
get_reporter().register_handler(AllureHandler())
27+
logger = logging.getLogger("NeoLogger")
28+
29+
30+
def pytest_addoption(parser):
31+
parser.addoption(
32+
"--persist-env", action="store_true", default=False, help="persist deployed env"
33+
)
34+
parser.addoption("--load-env", action="store", help="load persisted env from file")
35+
36+
37+
def _run_with_passwd(cmd: str, password: str) -> str:
38+
child = pexpect.spawn(cmd)
39+
child.delaybeforesend = 1
40+
child.expect(".*")
41+
child.sendline(f"{password}\r")
42+
if sys.platform == "darwin":
43+
child.expect(pexpect.EOF)
44+
cmd = child.before
45+
else:
46+
child.wait()
47+
cmd = child.read()
48+
return cmd.decode()
49+
750

851
def read_config(config_file):
952
config = configparser.ConfigParser()
1053
config.read(config_file)
1154
return config
1255

1356

57+
@allure.step("Init S3 Credentials")
58+
def init_s3_credentials(
59+
wallet: NodeWallet,
60+
neofs_env: NeoFSEnv,
61+
) -> tuple:
62+
gate_public_key = get_last_public_key_from_wallet(
63+
neofs_env.s3_gw.wallet.path, neofs_env.s3_gw.wallet.password
64+
)
65+
66+
cmd = (
67+
f"{neofs_env.neofs_s3_authmate_path} --debug --with-log --timeout 1m "
68+
f"issue-secret --wallet {wallet.path} --gate-public-key={gate_public_key} "
69+
f"--peer {neofs_env.storage_nodes[0].endpoint} "
70+
f"--bearer-rules {os.getcwd()}/bearer_rules.json --container-placement-policy 'REP 1' "
71+
f"--container-policy {os.getcwd()}/container_policy.json"
72+
)
73+
74+
logger.info(f"Executing command: {cmd}")
75+
76+
try:
77+
output = _run_with_passwd(cmd, wallet.password)
78+
79+
logger.info(f"output: {output}")
80+
81+
# output contains some debug info and then several JSON structures, so we find each
82+
# JSON structure by curly brackets (naive approach, but works while JSON is not nested)
83+
# and then we take JSON containing secret_access_key
84+
json_blocks = re.findall(r"\{.*?\}", output, re.DOTALL)
85+
for json_block in json_blocks:
86+
try:
87+
parsed_json_block = json.loads(json_block)
88+
if "secret_access_key" in parsed_json_block:
89+
return (
90+
parsed_json_block["access_key_id"],
91+
parsed_json_block["secret_access_key"],
92+
parsed_json_block["wallet_public_key"],
93+
get_last_address_from_wallet(wallet.path, wallet.password),
94+
)
95+
except json.JSONDecodeError:
96+
raise AssertionError(f"Could not parse info from output\n{output}")
97+
raise AssertionError(f"Could not find AWS credentials in output:\n{output}")
98+
except Exception as exc:
99+
raise RuntimeError(
100+
f"Failed to init s3 credentials because of error\n{exc}"
101+
) from exc
102+
103+
104+
def create_dir(dir_path: str) -> None:
105+
with allure.step("Create directory"):
106+
remove_dir(dir_path)
107+
os.mkdir(dir_path)
108+
109+
110+
def remove_dir(dir_path: str) -> None:
111+
with allure.step("Remove directory"):
112+
shutil.rmtree(dir_path, ignore_errors=True)
113+
114+
115+
@pytest.fixture(scope="session")
116+
@allure.title("Prepare tmp directory")
117+
def temp_directory() -> str:
118+
with allure.step("Prepare tmp directory"):
119+
full_path = os.path.join(os.getcwd(), ASSETS_DIR)
120+
create_dir(full_path)
121+
122+
yield full_path
123+
124+
with allure.step("Remove tmp directory"):
125+
remove_dir(full_path)
126+
127+
128+
@pytest.fixture(scope="session", autouse=True)
129+
def neofs_setup(request, temp_directory):
130+
if request.config.getoption("--load-env"):
131+
neofs_env = NeoFSEnv.load(request.config.getoption("--load-env"))
132+
else:
133+
neofs_env = NeoFSEnv.simple()
134+
135+
neofs_env.neofs_adm().morph.set_config(
136+
rpc_endpoint=f"http://{neofs_env.morph_rpc}",
137+
alphabet_wallets=neofs_env.alphabet_wallets_dir,
138+
post_data="ContainerFee=0 ContainerAliasFee=0 MaxObjectSize=524288",
139+
)
140+
time.sleep(30)
141+
142+
main_wallet = create_wallet()
143+
144+
(
145+
main_access_key_id,
146+
main_secret_access_key,
147+
main_wallet_public_key,
148+
main_wallet_address,
149+
) = init_s3_credentials(main_wallet, neofs_env)
150+
151+
alt_wallet = create_wallet()
152+
153+
(alt_access_key_id, alt_secret_access_key, alt_wallet_public_key, _) = (
154+
init_s3_credentials(alt_wallet, neofs_env)
155+
)
156+
157+
jinja_env = jinja2.Environment()
158+
config_template = Path("s3tests.conf.SAMPLE").read_text()
159+
jinja_template = jinja_env.from_string(config_template)
160+
rendered_config = jinja_template.render(
161+
S3_HOST=neofs_env.s3_gw.address.split(":")[0],
162+
S3_PORT=neofs_env.s3_gw.address.split(":")[1],
163+
S3_TLS=True,
164+
S3_MAIN_DISPLAY_NAME=main_wallet_address,
165+
S3_MAIN_USER_ID=main_wallet_public_key,
166+
S3_MAIN_ACCESS_KEY=main_access_key_id,
167+
S3_MAIN_SECRET_KEY=main_secret_access_key,
168+
S3_ALT_USER_ID=alt_wallet_public_key,
169+
S3_ALT_ACCESS_KEY=alt_access_key_id,
170+
S3_ALT_SECRET_KEY=alt_secret_access_key,
171+
S3_TENANT_USER_ID=alt_wallet_public_key,
172+
S3_TENANT_ACCESS_KEY=alt_access_key_id,
173+
S3_TENANT_SECRET_KEY=alt_secret_access_key,
174+
S3_IAM_USER_ID=alt_wallet_public_key,
175+
S3_IAM_ACCESS_KEY=alt_access_key_id,
176+
S3_IAM_SECRET_KEY=alt_secret_access_key,
177+
)
178+
with open("s3tests.conf", mode="w") as fp:
179+
fp.write(rendered_config)
180+
181+
os.environ["S3TEST_CONF"] = "s3tests.conf"
182+
183+
yield neofs_env
184+
185+
if request.config.getoption("--persist-env"):
186+
neofs_env.persist()
187+
else:
188+
if not request.config.getoption("--load-env"):
189+
neofs_env.kill()
190+
191+
logs_path = os.path.join(os.getcwd(), ASSETS_DIR, "logs")
192+
os.makedirs(logs_path, exist_ok=True)
193+
194+
shutil.copyfile(neofs_env.s3_gw.stderr, f"{logs_path}/s3_gw_log.txt")
195+
for idx, ir in enumerate(neofs_env.inner_ring_nodes):
196+
shutil.copyfile(ir.stderr, f"{logs_path}/ir_{idx}_log.txt")
197+
for idx, sn in enumerate(neofs_env.storage_nodes):
198+
shutil.copyfile(sn.stderr, f"{logs_path}/sn_{idx}_log.txt")
199+
200+
logs_zip_file_path = shutil.make_archive("neofs_logs", "zip", logs_path)
201+
allure.attach.file(logs_zip_file_path, name="neofs logs", extension="zip")
202+
203+
14204
@pytest.fixture(scope="session", autouse=True)
15-
def nose_setup():
205+
def nose_setup(neofs_setup):
16206
setup()

container_policy.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rep-1": "REP 1",
3+
"rep-3": "REP 3",
4+
"complex": "REP 1 IN X CBF 1 SELECT 1 FROM * AS X"
5+
}

neofs-testcases

Submodule neofs-testcases added at fa039ce

pytest.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
[pytest]
2+
log_cli = 1
3+
log_cli_level = debug
4+
log_cli_format = [%(threadName)s] %(asctime)s [%(levelname)4s] %(message)s
5+
log_format = [%(threadName)s] %(asctime)s [%(levelname)4s] %(message)s [%(threadName)s]
6+
log_cli_date_format = %Y-%m-%d %H:%M:%S
7+
log_date_format = %H:%M:%S
28
markers =
39
abac_test
410
appendobject

requirements.txt

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
PyYAML
22
boto >=2.6.0
3-
boto3 >=1.0.0
4-
botocore
53
munch >=2.0.0
64
# 0.14 switches to libev, that means bootstrap needs to change too
75
gevent >=1.0
86
isodate >=0.4.4
9-
requests >=2.23.0
107
pytz >=2011k
118
httplib2
129
lxml
1310
tox
14-
pytest ==7.3.1
15-
allure-pytest ==2.9.45
1611
pytest-nose-attrib ==0.1.1
1712
pytest-timeout ==2.1.0
18-
allure-combine ==1.0.8
13+
allure-combine==1.0.11
14+
allure-pytest==2.13.4
15+
base58==2.1.1
16+
black==24.3.0
17+
botocore==1.34.72
18+
boto3==1.34.72
19+
docker==7.0.0
20+
isort==5.13.2
21+
jinja2==3.1.4
22+
neo-mamba==2.6.0
23+
paramiko==3.4.0
24+
pexpect==4.9.0
25+
pytest==7.3.1
26+
PyYAML==6.0.1
27+
python-dotenv==1.0.1
28+
python-dateutil==2.9.0
29+
pytest-lazy-fixture==0.6.3
30+
requests==2.31.0
31+
tenacity==8.2.3
32+
urllib3==2.2.1

0 commit comments

Comments
 (0)