Skip to content

Commit bc32093

Browse files
authored
Adapt http and s3 tests to new dynamic env (#708)
2 parents 9460496 + b9368d6 commit bc32093

22 files changed

+2813
-43
lines changed

.github/workflows/run-tests.yml

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,21 @@ jobs:
8282
file: 'neofs-node-amd64'
8383
target: 'neofs-testcases/neofs-node'
8484

85-
- name: Checkout neofs-s3-gw repository
86-
uses: actions/checkout@v4
85+
- name: Download latest stable neofs-s3-gw
86+
uses: dsaltares/[email protected]
87+
with:
88+
repo: 'nspcc-dev/neofs-s3-gw'
89+
version: 'tags/v0.29.0'
90+
file: 'neofs-s3-gw-linux-amd64'
91+
target: 'neofs-testcases/neofs-s3-gw'
92+
93+
- name: Download latest stable neofs-s3-gw-authmate
94+
uses: dsaltares/[email protected]
8795
with:
88-
repository: nspcc-dev/neofs-s3-gw
89-
ref: '014a5bf493d00b8cce478e2c96c84ad9de8fe617'
90-
path: neofs-s3-gw
96+
repo: 'nspcc-dev/neofs-s3-gw'
97+
version: 'tags/v0.29.0'
98+
file: 'neofs-s3-authmate-linux-amd64'
99+
target: 'neofs-testcases/neofs-s3-authmate'
91100

92101
- name: Download latest stable neofs-rest-gw
93102
uses: dsaltares/[email protected]
@@ -123,15 +132,10 @@ jobs:
123132
sudo chmod a+x neofs-rest-gw
124133
sudo chmod a+x neofs-http-gw
125134
sudo chmod a+x neo-go
135+
sudo chmod a+x neofs-s3-authmate
136+
sudo chmod a+x neofs-s3-gw
126137
working-directory: neofs-testcases
127138

128-
- name: Set up Go
129-
uses: actions/setup-go@v4
130-
with:
131-
cache: true
132-
go-version: '1.20'
133-
- run: go version
134-
135139
- name: Set up Python
136140
uses: actions/setup-python@v4
137141
with:
@@ -162,24 +166,11 @@ jobs:
162166
sudo python ./tools/src/openssl_config_fix.py
163167
working-directory: neofs-testcases
164168

165-
- name: Build neofs-s3-gw
166-
timeout-minutes: 5
167-
run: |
168-
make all
169-
echo "$(pwd)/bin" >> $GITHUB_PATH
170-
working-directory: neofs-s3-gw
171-
172-
- name: Copy binaries to testcases directory
173-
timeout-minutes: 30
174-
run: |
175-
cp ${GITHUB_WORKSPACE}/neofs-s3-gw/bin/* .
176-
echo "$(pwd)" >> $GITHUB_PATH
177-
working-directory: neofs-testcases
178-
179169
- name: Prepare venv
180170
timeout-minutes: 30
181171
run: |
182172
make venv.no-dev-env-pytest
173+
echo "$(pwd)" >> $GITHUB_PATH
183174
working-directory: neofs-testcases
184175

185176
- name: Log environment
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from dataclasses import dataclass
2+
from typing import Optional
3+
4+
5+
@dataclass
6+
class ObjectRef:
7+
cid: str
8+
oid: str
9+
10+
11+
@dataclass
12+
class LockObjectInfo(ObjectRef):
13+
lifetime: Optional[int] = None
14+
expire_at: Optional[int] = None
15+
16+
17+
@dataclass
18+
class StorageObjectInfo(ObjectRef):
19+
size: Optional[int] = None
20+
wallet_file_path: Optional[str] = None
21+
file_path: Optional[str] = None
22+
file_hash: Optional[str] = None
23+
attributes: Optional[list[dict[str, str]]] = None
24+
tombstone: Optional[str] = None
25+
locks: Optional[list[LockObjectInfo]] = None
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import random
2+
3+
import allure
4+
import neofs_verbs
5+
from grpc_responses import OBJECT_NOT_FOUND, error_matches_status
6+
from neofs_testlib.env.env import StorageNode
7+
from neofs_testlib.shell import Shell
8+
from python_keywords.http_gate import assert_hashes_are_equal, get_via_http_gate
9+
from python_keywords.neofs_verbs import get_object
10+
11+
12+
def get_object_and_verify_hashes(
13+
oid: str,
14+
file_name: str,
15+
wallet: str,
16+
cid: str,
17+
shell: Shell,
18+
nodes: list[StorageNode],
19+
endpoint: str,
20+
object_getter=None,
21+
) -> None:
22+
nodes_list = get_nodes_without_object(
23+
wallet=wallet,
24+
cid=cid,
25+
oid=oid,
26+
shell=shell,
27+
nodes=nodes,
28+
)
29+
# for some reason we can face with case when nodes_list is empty due to object resides in all nodes
30+
if nodes_list:
31+
random_node = random.choice(nodes_list)
32+
else:
33+
random_node = random.choice(nodes)
34+
35+
object_getter = object_getter or get_via_http_gate
36+
37+
got_file_path = get_object(
38+
wallet=wallet,
39+
cid=cid,
40+
oid=oid,
41+
shell=shell,
42+
endpoint=random_node.endpoint,
43+
)
44+
got_file_path_http = object_getter(cid=cid, oid=oid, endpoint=endpoint)
45+
46+
assert_hashes_are_equal(file_name, got_file_path, got_file_path_http)
47+
48+
49+
@allure.step("Get Nodes Without Object")
50+
def get_nodes_without_object(
51+
wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
52+
) -> list[StorageNode]:
53+
"""
54+
The function returns list of nodes which do not store
55+
the given object.
56+
Args:
57+
wallet (str): the path to the wallet on whose behalf
58+
we request the nodes
59+
cid (str): ID of the container which store the object
60+
oid (str): object ID
61+
shell: executor for cli command
62+
Returns:
63+
(list): nodes which do not store the object
64+
"""
65+
nodes_list = []
66+
for node in nodes:
67+
try:
68+
res = neofs_verbs.head_object(
69+
wallet, cid, oid, shell=shell, endpoint=node.endpoint, is_direct=True
70+
)
71+
if res is None:
72+
nodes_list.append(node)
73+
except Exception as err:
74+
if error_matches_status(err, OBJECT_NOT_FOUND):
75+
nodes_list.append(node)
76+
else:
77+
raise Exception(f"Got error {err} on head object command") from err
78+
return nodes_list
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import logging
2+
3+
import allure
4+
import neofs_verbs
5+
from neofs_testlib.env.env import StorageNode
6+
from neofs_testlib.shell import Shell
7+
8+
logger = logging.getLogger("NeoLogger")
9+
10+
11+
@allure.step("Get Simple Object Copies")
12+
def get_simple_object_copies(
13+
wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
14+
) -> int:
15+
"""
16+
To figure out the number of a simple object copies, only direct
17+
HEAD requests should be made to the every node of the container.
18+
We consider non-empty HEAD response as a stored object copy.
19+
Args:
20+
wallet (str): the path to the wallet on whose behalf the
21+
copies are got
22+
cid (str): ID of the container
23+
oid (str): ID of the Object
24+
shell: executor for cli command
25+
nodes: nodes to search on
26+
Returns:
27+
(int): the number of object copies in the container
28+
"""
29+
copies = 0
30+
for node in nodes:
31+
try:
32+
response = neofs_verbs.head_object(
33+
wallet, cid, oid, shell=shell, endpoint=node.endpoint, is_direct=True
34+
)
35+
if response:
36+
logger.info(f"Found object {oid} on node {node}")
37+
copies += 1
38+
except Exception:
39+
logger.info(f"No {oid} object copy found on {node}, continue")
40+
continue
41+
return copies

dynamic_env_pytest_tests/pytest.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[pytest]
22
log_cli = 1
33
log_cli_level = debug
4-
log_cli_format = %(asctime)s [%(levelname)4s] %(message)s
5-
log_format = %(asctime)s [%(levelname)4s] %(message)s
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]
66
log_cli_date_format = %Y-%m-%d %H:%M:%S
77
log_date_format = %H:%M:%S
88
markers =

dynamic_env_pytest_tests/tests/conftest.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import shutil
33
import uuid
4+
import time
45
from typing import Optional
56

67
import allure
@@ -36,8 +37,9 @@ def neofs_env(request):
3637
neofs_env.neofs_adm().morph.set_config(
3738
rpc_endpoint=f"http://{neofs_env.morph_rpc}",
3839
alphabet_wallets=neofs_env.alphabet_wallets_dir,
39-
post_data=f"ContainerFee=0 ContainerAliasFee=0",
40+
post_data=f"ContainerFee=0 ContainerAliasFee=0 MaxObjectSize=524288",
4041
)
42+
time.sleep(30)
4143

4244
yield neofs_env
4345

@@ -46,6 +48,19 @@ def neofs_env(request):
4648
else:
4749
if not request.config.getoption("--load-env"):
4850
neofs_env.kill()
51+
52+
logs_path = os.path.join(os.getcwd(), ASSETS_DIR, "logs")
53+
os.makedirs(logs_path, exist_ok=True)
54+
55+
shutil.copyfile(neofs_env.s3_gw.stderr, f"{logs_path}/s3_gw_log.txt")
56+
shutil.copyfile(neofs_env.http_gw.stderr, f"{logs_path}/http_gw_log.txt")
57+
for idx, ir in enumerate(neofs_env.inner_ring_nodes):
58+
shutil.copyfile(ir.stderr, f"{logs_path}/ir_{idx}_log.txt")
59+
for idx, sn in enumerate(neofs_env.storage_nodes):
60+
shutil.copyfile(sn.stderr, f"{logs_path}/sn_{idx}_log.txt")
61+
62+
logs_zip_file_path = shutil.make_archive("neofs_logs", "zip", logs_path)
63+
allure.attach.file(logs_zip_file_path, name="neofs logs", extension="zip")
4964

5065

5166
@pytest.fixture(scope="session")

0 commit comments

Comments
 (0)