forked from TrueCloudLab/frostfs-testlib
Compare commits
6 commits
master
...
new-comman
Author | SHA1 | Date | |
---|---|---|---|
d4e56b347e | |||
c2aa41e5dc | |||
8e446ccb96 | |||
9c9fb7878a | |||
3a799afdcf | |||
b610e04a7b |
7 changed files with 172 additions and 8 deletions
|
@ -9,6 +9,8 @@ class FrostfsCliContainer(CliCommand):
|
||||||
self,
|
self,
|
||||||
rpc_endpoint: str,
|
rpc_endpoint: str,
|
||||||
wallet: Optional[str] = None,
|
wallet: Optional[str] = None,
|
||||||
|
nns_zone: Optional[str] = None,
|
||||||
|
nns_name: Optional[str] = None,
|
||||||
address: Optional[str] = None,
|
address: Optional[str] = None,
|
||||||
attributes: Optional[dict] = None,
|
attributes: Optional[dict] = None,
|
||||||
basic_acl: Optional[str] = None,
|
basic_acl: Optional[str] = None,
|
||||||
|
@ -45,6 +47,8 @@ class FrostfsCliContainer(CliCommand):
|
||||||
wallet: WIF (NEP-2) string or path to the wallet or binary key.
|
wallet: WIF (NEP-2) string or path to the wallet or binary key.
|
||||||
xhdr: Dict with request X-Headers.
|
xhdr: Dict with request X-Headers.
|
||||||
timeout: Timeout for the operation (default 15s).
|
timeout: Timeout for the operation (default 15s).
|
||||||
|
nns_zone: Container nns zone attribute.
|
||||||
|
nns_name: Container nns name attribute.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Command's result.
|
Command's result.
|
||||||
|
|
|
@ -79,3 +79,154 @@ class FrostfsCliControl(CliCommand):
|
||||||
"control drop-objects",
|
"control drop-objects",
|
||||||
**{param: value for param, value in locals().items() if param not in ["self"]},
|
**{param: value for param, value in locals().items() if param not in ["self"]},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def add_rule(
|
||||||
|
self,
|
||||||
|
endpoint: str,
|
||||||
|
chain_id: str,
|
||||||
|
target_name: str,
|
||||||
|
target_type: str,
|
||||||
|
rule: Optional[list[str]] = None,
|
||||||
|
path: Optional[str] = None,
|
||||||
|
chain_id_hex: Optional[bool] = None,
|
||||||
|
wallet: Optional[str] = None,
|
||||||
|
address: Optional[str] = None,
|
||||||
|
timeout: Optional[str] = None,
|
||||||
|
) -> CommandResult:
|
||||||
|
"""Drop objects from the node's local storage
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address: Address of wallet account
|
||||||
|
chain-id: Assign ID to the parsed chain
|
||||||
|
chain-id-hex: Flag to parse chain ID as hex
|
||||||
|
endpoint: Remote node control address (as 'multiaddr' or '<host>:<port>')
|
||||||
|
path: Path to encoded chain in JSON or binary format
|
||||||
|
rule: Rule statement
|
||||||
|
target-name: Resource name in APE resource name format
|
||||||
|
target-type: Resource type(container/namespace)
|
||||||
|
timeout: Timeout for an operation (default 15s)
|
||||||
|
wallet: Path to the wallet or binary key
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Command`s result.
|
||||||
|
"""
|
||||||
|
return self._execute(
|
||||||
|
"control add-rule",
|
||||||
|
**{param: value for param, value in locals().items() if param not in ["self"]},
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_rule(
|
||||||
|
self,
|
||||||
|
endpoint: str,
|
||||||
|
chain_id: str,
|
||||||
|
target_name: str,
|
||||||
|
target_type: str,
|
||||||
|
chain_id_hex: Optional[bool] = None,
|
||||||
|
wallet: Optional[str] = None,
|
||||||
|
address: Optional[str] = None,
|
||||||
|
timeout: Optional[str] = None,
|
||||||
|
) -> CommandResult:
|
||||||
|
"""Drop objects from the node's local storage
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address string Address of wallet account
|
||||||
|
chain-id string Chain id
|
||||||
|
chain-id-hex Flag to parse chain ID as hex
|
||||||
|
endpoint string Remote node control address (as 'multiaddr' or '<host>:<port>')
|
||||||
|
target-name string Resource name in APE resource name format
|
||||||
|
target-type string Resource type(container/namespace)
|
||||||
|
timeout duration Timeout for an operation (default 15s)
|
||||||
|
wallet string Path to the wallet or binary key
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Command`s result.
|
||||||
|
"""
|
||||||
|
return self._execute(
|
||||||
|
"control get-rule",
|
||||||
|
**{param: value for param, value in locals().items() if param not in ["self"]},
|
||||||
|
)
|
||||||
|
|
||||||
|
def list_rules(
|
||||||
|
self,
|
||||||
|
endpoint: str,
|
||||||
|
target_name: str,
|
||||||
|
target_type: str,
|
||||||
|
wallet: Optional[str] = None,
|
||||||
|
address: Optional[str] = None,
|
||||||
|
timeout: Optional[str] = None,
|
||||||
|
) -> CommandResult:
|
||||||
|
"""Drop objects from the node's local storage
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address: Address of wallet account
|
||||||
|
endpoint: Remote node control address (as 'multiaddr' or '<host>:<port>')
|
||||||
|
target-name: Resource name in APE resource name format
|
||||||
|
target-type: Resource type(container/namespace)
|
||||||
|
timeout: Timeout for an operation (default 15s)
|
||||||
|
wallet: Path to the wallet or binary key
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Command`s result.
|
||||||
|
"""
|
||||||
|
return self._execute(
|
||||||
|
"control list-rules",
|
||||||
|
**{param: value for param, value in locals().items() if param not in ["self"]},
|
||||||
|
)
|
||||||
|
|
||||||
|
def list_targets(
|
||||||
|
self,
|
||||||
|
endpoint: str,
|
||||||
|
chain_name: str,
|
||||||
|
wallet: Optional[str] = None,
|
||||||
|
address: Optional[str] = None,
|
||||||
|
timeout: Optional[str] = None,
|
||||||
|
) -> CommandResult:
|
||||||
|
"""Drop objects from the node's local storage
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address: Address of wallet account
|
||||||
|
chain-name: Chain name(ingress|s3)
|
||||||
|
endpoint: Remote node control address (as 'multiaddr' or '<host>:<port>')
|
||||||
|
timeout: Timeout for an operation (default 15s)
|
||||||
|
wallet: Path to the wallet or binary key
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Command`s result.
|
||||||
|
"""
|
||||||
|
return self._execute(
|
||||||
|
"control list-targets",
|
||||||
|
**{param: value for param, value in locals().items() if param not in ["self"]},
|
||||||
|
)
|
||||||
|
|
||||||
|
def remove_rule(
|
||||||
|
self,
|
||||||
|
endpoint: str,
|
||||||
|
chain_id: str,
|
||||||
|
target_name: str,
|
||||||
|
target_type: str,
|
||||||
|
all: Optional[bool] = None,
|
||||||
|
chain_id_hex: Optional[bool] = None,
|
||||||
|
wallet: Optional[str] = None,
|
||||||
|
address: Optional[str] = None,
|
||||||
|
timeout: Optional[str] = None,
|
||||||
|
) -> CommandResult:
|
||||||
|
"""Drop objects from the node's local storage
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address: Address of wallet account
|
||||||
|
all: Remove all chains
|
||||||
|
chain-id: Assign ID to the parsed chain
|
||||||
|
chain-id-hex: Flag to parse chain ID as hex
|
||||||
|
endpoint: Remote node control address (as 'multiaddr' or '<host>:<port>')
|
||||||
|
target-name: Resource name in APE resource name format
|
||||||
|
target-type: Resource type(container/namespace)
|
||||||
|
timeout: Timeout for an operation (default 15s)
|
||||||
|
wallet: Path to the wallet or binary key
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Command`s result.
|
||||||
|
"""
|
||||||
|
return self._execute(
|
||||||
|
"control remove-rule",
|
||||||
|
**{param: value for param, value in locals().items() if param not in ["self"]},
|
||||||
|
)
|
||||||
|
|
|
@ -86,7 +86,7 @@ class SummarizedStats:
|
||||||
target.latencies.by_node[node_key] = operation.latency
|
target.latencies.by_node[node_key] = operation.latency
|
||||||
target.throughput += operation.throughput
|
target.throughput += operation.throughput
|
||||||
target.errors.threshold = load_params.error_threshold
|
target.errors.threshold = load_params.error_threshold
|
||||||
target.total_bytes = operation.total_bytes
|
target.total_bytes += operation.total_bytes
|
||||||
if operation.failed_iterations:
|
if operation.failed_iterations:
|
||||||
target.errors.by_node[node_key] = operation.failed_iterations
|
target.errors.by_node[node_key] = operation.failed_iterations
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,8 @@ class LoadParams:
|
||||||
)
|
)
|
||||||
# Percentage of filling of all data disks on all nodes
|
# Percentage of filling of all data disks on all nodes
|
||||||
fill_percent: Optional[float] = None
|
fill_percent: Optional[float] = None
|
||||||
|
# if specified, max payload size in GB of the storage engine. If the storage engine is already full, no new objects will be saved.
|
||||||
|
max_total_size_gb: Optional[float] = metadata_field([LoadScenario.LOCAL, LoadScenario.S3_LOCAL], None, "MAX_TOTAL_SIZE_GB")
|
||||||
# if set, the payload is generated on the fly and is not read into memory fully.
|
# if set, the payload is generated on the fly and is not read into memory fully.
|
||||||
streaming: Optional[int] = metadata_field(all_load_scenarios, None, "STREAMING", False)
|
streaming: Optional[int] = metadata_field(all_load_scenarios, None, "STREAMING", False)
|
||||||
# Output format
|
# Output format
|
||||||
|
|
|
@ -729,7 +729,10 @@ class AwsCliClient(S3ClientWrapper):
|
||||||
f"--key {key} --upload-id {upload_id} --multipart-upload file://{file_path} "
|
f"--key {key} --upload-id {upload_id} --multipart-upload file://{file_path} "
|
||||||
f"--endpoint-url {self.s3gate_endpoint} --profile {self.profile}"
|
f"--endpoint-url {self.s3gate_endpoint} --profile {self.profile}"
|
||||||
)
|
)
|
||||||
self.local_shell.exec(cmd)
|
output = self.local_shell.exec(cmd).stdout
|
||||||
|
response = self._to_json(output)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
@reporter.step("Put object lock configuration")
|
@reporter.step("Put object lock configuration")
|
||||||
def put_object_lock_configuration(self, bucket: str, configuration: dict) -> dict:
|
def put_object_lock_configuration(self, bucket: str, configuration: dict) -> dict:
|
||||||
|
|
|
@ -135,7 +135,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
|
||||||
|
|
||||||
s3_bucket = self.boto3_client.create_bucket(**params)
|
s3_bucket = self.boto3_client.create_bucket(**params)
|
||||||
log_command_execution(f"Created S3 bucket {bucket}", s3_bucket)
|
log_command_execution(f"Created S3 bucket {bucket}", s3_bucket)
|
||||||
sleep(S3_SYNC_WAIT_TIME * 10)
|
sleep(S3_SYNC_WAIT_TIME)
|
||||||
return bucket
|
return bucket
|
||||||
|
|
||||||
@reporter.step("List buckets S3")
|
@reporter.step("List buckets S3")
|
||||||
|
@ -156,7 +156,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
|
||||||
def delete_bucket(self, bucket: str) -> None:
|
def delete_bucket(self, bucket: str) -> None:
|
||||||
response = self.boto3_client.delete_bucket(Bucket=bucket)
|
response = self.boto3_client.delete_bucket(Bucket=bucket)
|
||||||
log_command_execution("S3 Delete bucket result", response)
|
log_command_execution("S3 Delete bucket result", response)
|
||||||
sleep(S3_SYNC_WAIT_TIME * 10)
|
sleep(S3_SYNC_WAIT_TIME)
|
||||||
|
|
||||||
@reporter.step("Head bucket S3")
|
@reporter.step("Head bucket S3")
|
||||||
@report_error
|
@report_error
|
||||||
|
@ -372,7 +372,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
|
||||||
}
|
}
|
||||||
response = self.boto3_client.delete_object(**params)
|
response = self.boto3_client.delete_object(**params)
|
||||||
log_command_execution("S3 Delete object result", response)
|
log_command_execution("S3 Delete object result", response)
|
||||||
sleep(S3_SYNC_WAIT_TIME * 10)
|
sleep(S3_SYNC_WAIT_TIME)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@reporter.step("Delete objects S3")
|
@reporter.step("Delete objects S3")
|
||||||
|
@ -383,7 +383,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
|
||||||
assert (
|
assert (
|
||||||
"Errors" not in response
|
"Errors" not in response
|
||||||
), f'The following objects have not been deleted: {[err_info["Key"] for err_info in response["Errors"]]}.\nError Message: {response["Errors"]["Message"]}'
|
), f'The following objects have not been deleted: {[err_info["Key"] for err_info in response["Errors"]]}.\nError Message: {response["Errors"]["Message"]}'
|
||||||
sleep(S3_SYNC_WAIT_TIME * 10)
|
sleep(S3_SYNC_WAIT_TIME)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@reporter.step("Delete object versions S3")
|
@reporter.step("Delete object versions S3")
|
||||||
|
@ -571,6 +571,8 @@ class Boto3ClientWrapper(S3ClientWrapper):
|
||||||
)
|
)
|
||||||
log_command_execution("S3 Complete multipart upload", response)
|
log_command_execution("S3 Complete multipart upload", response)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
@reporter.step("Put object retention")
|
@reporter.step("Put object retention")
|
||||||
@report_error
|
@report_error
|
||||||
def put_object_retention(
|
def put_object_retention(
|
||||||
|
|
|
@ -13,6 +13,7 @@ from frostfs_testlib.resources.common import ASSETS_DIR
|
||||||
from frostfs_testlib.shell import Shell
|
from frostfs_testlib.shell import Shell
|
||||||
from frostfs_testlib.storage.cluster import Cluster, ClusterNode
|
from frostfs_testlib.storage.cluster import Cluster, ClusterNode
|
||||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
|
from frostfs_testlib.testing import wait_for_success
|
||||||
from frostfs_testlib.utils import json_utils
|
from frostfs_testlib.utils import json_utils
|
||||||
from frostfs_testlib.utils.cli_utils import parse_cmd_table, parse_netmap_output
|
from frostfs_testlib.utils.cli_utils import parse_cmd_table, parse_netmap_output
|
||||||
|
|
||||||
|
@ -695,6 +696,7 @@ def neo_go_query_height(shell: Shell, endpoint: str) -> dict:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@wait_for_success()
|
||||||
@reporter.step("Search object nodes")
|
@reporter.step("Search object nodes")
|
||||||
def get_object_nodes(
|
def get_object_nodes(
|
||||||
cluster: Cluster,
|
cluster: Cluster,
|
||||||
|
|
Loading…
Reference in a new issue