Skip to content

Commit 32fba65

Browse files
authored
tests: add write cache test (#948)
2 parents fa97a79 + e7b1441 commit 32fba65

File tree

19 files changed

+233
-44
lines changed

19 files changed

+233
-44
lines changed

neofs-testlib/neofs_testlib/cli/neofs_cli/shards.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional, List
1+
from typing import List, Optional
22

33
from neofs_testlib.cli.cli_command import CliCommand
44
from neofs_testlib.shell import CommandResult
@@ -8,18 +8,18 @@ class NeofsCliShards(CliCommand):
88
def flush_cache(
99
self,
1010
endpoint: str,
11-
wallet: str,
12-
shards_id: Optional[list[str]],
11+
wallet: Optional[str] = None,
12+
shards_id: Optional[list[str]] = None,
1313
address: Optional[str] = None,
14-
all_shards: bool = False,
14+
all: bool = False,
1515
) -> CommandResult:
1616
"""
1717
Flush objects from the write-cache to the main storage.
1818
1919
Args:
2020
address: Address of wallet account.
2121
shards_id: List of shard IDs in base58 encoding.
22-
all_shards: Process all shards.
22+
all: Process all shards.
2323
endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
2424
wallet: WIF (NEP-2) string or path to the wallet or binary key.
2525
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
from typing import Optional
22

33
from neofs_testlib.cli.neofs_lens.objects import NeofsLensObject
4+
from neofs_testlib.cli.neofs_lens.storage import NeofsLensStorage
5+
from neofs_testlib.cli.neofs_lens.write_cache import NeofsLensWriteCache
46
from neofs_testlib.shell import Shell
57

68

79
class NeofsLens:
810
object: Optional[NeofsLensObject] = None
11+
write_cache: Optional[NeofsLensWriteCache] = None
12+
storage: Optional[NeofsLensStorage] = None
913

1014
def __init__(self, shell: Shell, neofs_lens_exec_path: str):
1115
self.object = NeofsLensObject(shell, neofs_lens_exec_path)
16+
self.write_cache = NeofsLensWriteCache(shell, neofs_lens_exec_path)
17+
self.storage = NeofsLensStorage(shell, neofs_lens_exec_path)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from neofs_testlib.cli.cli_command import CliCommand
2+
from neofs_testlib.shell import CommandResult
3+
4+
5+
class NeofsLensStorage(CliCommand):
6+
def list(
7+
self,
8+
config: str,
9+
) -> CommandResult:
10+
"""
11+
List all objects stored in a blobstor (as registered in metabase).
12+
13+
Args:
14+
config: Path to file with storage node config
15+
Returns:
16+
Command's result.
17+
"""
18+
return self._execute(
19+
"storage list",
20+
**{param: value for param, value in locals().items() if param not in ["self"]},
21+
)
22+
23+
def get(
24+
self,
25+
address: str,
26+
config: str,
27+
) -> CommandResult:
28+
"""
29+
Get object from the NeoFS node's storage snapshot
30+
31+
Args:
32+
address: Object address
33+
config: Path to file with storage node config
34+
Returns:
35+
Command's result.
36+
"""
37+
return self._execute(
38+
"storage get",
39+
**{param: value for param, value in locals().items() if param not in ["self"]},
40+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from typing import Optional
2+
3+
from neofs_testlib.cli.cli_command import CliCommand
4+
from neofs_testlib.shell import CommandResult
5+
6+
7+
class NeofsLensWriteCache(CliCommand):
8+
def list(
9+
self,
10+
path: str,
11+
) -> CommandResult:
12+
"""
13+
List all objects stored in a write-cache.
14+
15+
Args:
16+
path: Path to storage engine component
17+
Returns:
18+
Command's result.
19+
"""
20+
return self._execute(
21+
"write-cache list",
22+
**{param: value for param, value in locals().items() if param not in ["self"]},
23+
)
24+
25+
def get(
26+
self,
27+
address: str,
28+
path: str,
29+
) -> CommandResult:
30+
"""
31+
Get specific object from a write-cache.
32+
33+
Args:
34+
address: Object address
35+
path: Path to storage engine component
36+
Returns:
37+
Command's result.
38+
"""
39+
return self._execute(
40+
"write-cache get",
41+
**{param: value for param, value in locals().items() if param not in ["self"]},
42+
)

neofs-testlib/neofs_testlib/env/env.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,16 @@ def deploy_inner_ring_nodes(self, count=1, with_main_chain=False):
182182
raise e
183183

184184
@allure.step("Deploy storage node")
185-
def deploy_storage_nodes(self, count=1, node_attrs: Optional[dict] = None):
185+
def deploy_storage_nodes(self, count=1, node_attrs: Optional[dict] = None, writecache=False):
186186
logger.info(f"Going to deploy {count} storage nodes")
187187
deploy_threads = []
188188
for idx in range(count):
189189
node_attrs_list = None
190190
if node_attrs:
191191
node_attrs_list = node_attrs.get(idx, None)
192-
new_storage_node = StorageNode(self, len(self.storage_nodes) + 1, node_attrs=node_attrs_list)
192+
new_storage_node = StorageNode(
193+
self, len(self.storage_nodes) + 1, writecache=writecache, node_attrs=node_attrs_list
194+
)
193195
self.storage_nodes.append(new_storage_node)
194196
deploy_threads.append(threading.Thread(target=new_storage_node.start))
195197
for t in deploy_threads:
@@ -642,6 +644,13 @@ def download_binary(repo: str, version: str, file: str, target: str):
642644
current_perm = os.stat(target)
643645
os.chmod(target, current_perm.st_mode | stat.S_IEXEC)
644646

647+
def get_binary_version(self, binary_path: str) -> str:
648+
raw_version_output = self._run_single_command(binary_path, "--version")
649+
for line in raw_version_output.splitlines():
650+
if "Version:" in line:
651+
return line.split("Version:")[1].strip()
652+
return ""
653+
645654
def _generate_temp_file(self, base_dir: str, extension: str = "", prefix: str = "tmp_file") -> str:
646655
file_path = f"{base_dir}/{prefix}_{''.join(random.choices(string.ascii_lowercase, k=10))}"
647656
if extension:
@@ -899,12 +908,17 @@ def __init__(self, neofs_env: NeoFSEnv, sn_dir: str):
899908
self.blobovnicza_path = neofs_env._generate_temp_file(sn_dir, prefix="shard_blobovnicza")
900909
self.fstree_path = neofs_env._generate_temp_dir(prefix="shards/shard_fstree")
901910
self.pilorama_path = neofs_env._generate_temp_file(sn_dir, prefix="shard_pilorama")
902-
self.wc_path = neofs_env._generate_temp_file(sn_dir, prefix="shard_wc")
911+
self.wc_path = neofs_env._generate_temp_dir(prefix="shards/shard_wc")
903912

904913

905914
class StorageNode:
906915
def __init__(
907-
self, neofs_env: NeoFSEnv, sn_number: int, node_attrs: Optional[list] = None, attrs: Optional[dict] = None
916+
self,
917+
neofs_env: NeoFSEnv,
918+
sn_number: int,
919+
writecache=False,
920+
node_attrs: Optional[list] = None,
921+
attrs: Optional[dict] = None,
908922
):
909923
self.neofs_env = neofs_env
910924
self.sn_dir = self.neofs_env._generate_temp_dir(prefix=f"sn_{sn_number}")
@@ -931,6 +945,7 @@ def __init__(
931945
self.process = None
932946
self.attrs = {}
933947
self.node_attrs = node_attrs
948+
self.writecache = writecache
934949
if attrs:
935950
self.attrs.update(attrs)
936951

@@ -966,6 +981,7 @@ def start(self, fresh=True):
966981
custom=Path(sn_config_template).is_file(),
967982
fschain_endpoint=self.neofs_env.fschain_rpc,
968983
shards=self.shards,
984+
writecache=self.writecache,
969985
wallet=self.wallet,
970986
state_file=self.state_file,
971987
pprof_address=self.pprof_address,
@@ -1010,7 +1026,7 @@ def delete_data(self):
10101026
os.remove(shard.blobovnicza_path)
10111027
os.rmdir(shard.fstree_path)
10121028
os.remove(shard.pilorama_path)
1013-
os.remove(shard.wc_path)
1029+
shutil.rmtree(shard.wc_path, ignore_errors=True)
10141030
os.remove(self.state_file)
10151031
self.shards = [Shard(), Shard()]
10161032

@@ -1022,6 +1038,7 @@ def delete_data(self):
10221038
custom=Path(sn_config_template).is_file(),
10231039
fschain_endpoint=self.neofs_env.fschain_rpc,
10241040
shards=self.shards,
1041+
writecache=self.writecache,
10251042
wallet=self.wallet,
10261043
state_file=self.state_file,
10271044
pprof_address=self.pprof_address,
@@ -1045,6 +1062,7 @@ def delete_metadata(self):
10451062
custom=Path(sn_config_template).is_file(),
10461063
fschain_endpoint=self.neofs_env.fschain_rpc,
10471064
shards=self.shards,
1065+
writecache=self.writecache,
10481066
wallet=self.wallet,
10491067
state_file=self.state_file,
10501068
pprof_address=self.pprof_address,
@@ -1097,13 +1115,6 @@ def _wait_until_not_ready(self):
10971115
assert "Health status: READY" not in result.stdout, "Health is ready"
10981116
assert "Network status: ONLINE" not in result.stdout, "Network is online"
10991117

1100-
def _get_version(self) -> str:
1101-
raw_version_output = self.neofs_env._run_single_command(self.neofs_env.neofs_node_path, "--version")
1102-
for line in raw_version_output.splitlines():
1103-
if "Version:" in line:
1104-
return line.split("Version:")[1].strip()
1105-
return ""
1106-
11071118

11081119
class S3_GW:
11091120
def __init__(self, neofs_env: NeoFSEnv):
@@ -1200,18 +1211,11 @@ def _generate_config(self):
12001211
peers=peers,
12011212
tree_service_endpoint=self.neofs_env.storage_nodes[0].endpoint,
12021213
listen_domain=self.neofs_env.domain,
1203-
s3_gw_version=self._get_version(),
1214+
s3_gw_version=self.neofs_env.get_binary_version(self.neofs_env.neofs_s3_gw_path),
12041215
pprof_address=self.pprof_address,
12051216
prometheus_address=self.prometheus_address,
12061217
)
12071218

1208-
def _get_version(self) -> str:
1209-
raw_version_output = self.neofs_env._run_single_command(self.neofs_env.neofs_s3_gw_path, "--version")
1210-
for line in raw_version_output.splitlines():
1211-
if "Version:" in line:
1212-
return line.split("Version:")[1].strip()
1213-
return ""
1214-
12151219
def _launch_process(self):
12161220
self.stdout = self.neofs_env._generate_temp_file(self.s3_gw_dir, prefix="s3gw_stdout")
12171221
self.stderr = self.neofs_env._generate_temp_file(self.s3_gw_dir, prefix="s3gw_stderr")

neofs-testlib/neofs_testlib/env/templates/sn.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ storage:
4444
shard:
4545
0:
4646
writecache:
47-
enabled: false
47+
enabled: {{ writecache }}
4848
path: {{ shards[0].wc_path }} # Write-cache root directory
4949

5050
metabase:
@@ -62,7 +62,7 @@ storage:
6262

6363
1:
6464
writecache:
65-
enabled: false
65+
enabled: {{ writecache }}
6666
path: {{ shards[1].wc_path }} # Write-cache root directory
6767

6868
metabase:

pytest_tests/tests/acl/test_eacl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ def test_extended_acl_operations_enforcement(self, wallets, eacl_container_with_
344344
def test_extended_acl_deny_all_operations_exclude_extended_role(
345345
self, wallets, eacl_container_with_objects, role: EACLRoleExtendedType
346346
):
347-
if self.neofs_env.storage_nodes[0]._get_version() > "0.44.2":
347+
if self.neofs_env.get_binary_version(self.neofs_env.neofs_node_path) > "0.44.2":
348348
pytest.skip("This test runs on 0.44.2 and below neofs-node versions")
349349
user_wallet = wallets.get_wallet()
350350
other_wallet, other_wallet_allow = wallets.get_wallets_list(EACLRole.OTHERS)[0:2]

pytest_tests/tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def neofs_env(temp_directory, artifacts_directory, request):
6060
os.remove(shard.blobovnicza_path)
6161
shutil.rmtree(shard.fstree_path, ignore_errors=True)
6262
os.remove(shard.pilorama_path)
63-
os.remove(shard.wc_path)
63+
shutil.rmtree(shard.wc_path, ignore_errors=True)
6464

6565
shutil.make_archive(
6666
os.path.join(get_assets_dir_path(), f"neofs_env_{neofs_env._id}"), "zip", neofs_env._env_dir

pytest_tests/tests/container/test_container.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def test_container_deletion_while_sn_down(
213213
object_should_be_gc_marked(self.neofs_env, node_to_stop, cid, oid)
214214

215215
def test_container_global_name(self, default_wallet, simple_object_size):
216-
if self.neofs_env.storage_nodes[0]._get_version() <= "0.43.0":
216+
if self.neofs_env.get_binary_version(self.neofs_env.neofs_node_path) <= "0.43.0":
217217
pytest.skip("This test runs only on post 0.43.0 node version")
218218

219219
with allure.step("Create container"):

pytest_tests/tests/metrics/test_sn_metrics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def test_sn_metrics(single_noded_env: NeoFSEnv, default_wallet: NodeWallet):
178178
f"invalid value for {metric}"
179179
)
180180

181-
node_version = single_noded_env.storage_nodes[0]._get_version()
181+
node_version = single_noded_env.get_binary_version(single_noded_env.neofs_node_path)
182182
assert after_metrics["neofs_node_version"][0]["params"]["version"] == node_version, (
183183
"invalid value for neofs_node_version"
184184
)

0 commit comments

Comments
 (0)