forked from TrueCloudLab/frostfs-testcases
Remove SIMPLE_OBJ_SIZE and COMPLEX_OBJ_SIZE from env
Signed-off-by: Vladimir Avdeev <v.avdeev@yadro.com>
This commit is contained in:
parent
76c5d40e63
commit
05924784ab
26 changed files with 322 additions and 253 deletions
|
@ -5,12 +5,12 @@ import uuid
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
from common import ASSETS_DIR, SIMPLE_OBJ_SIZE
|
from common import ASSETS_DIR
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
|
||||||
def generate_file(size: int = SIMPLE_OBJ_SIZE) -> str:
|
def generate_file(size: int) -> str:
|
||||||
"""Generates a binary file with the specified size in bytes.
|
"""Generates a binary file with the specified size in bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -28,6 +28,7 @@ def generate_file(size: int = SIMPLE_OBJ_SIZE) -> str:
|
||||||
|
|
||||||
|
|
||||||
def generate_file_with_content(
|
def generate_file_with_content(
|
||||||
|
size: int,
|
||||||
file_path: Optional[str] = None,
|
file_path: Optional[str] = None,
|
||||||
content: Optional[str] = None,
|
content: Optional[str] = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
|
@ -44,7 +45,7 @@ def generate_file_with_content(
|
||||||
"""
|
"""
|
||||||
mode = "w+"
|
mode = "w+"
|
||||||
if content is None:
|
if content is None:
|
||||||
content = os.urandom(SIMPLE_OBJ_SIZE)
|
content = os.urandom(size)
|
||||||
mode = "wb"
|
mode = "wb"
|
||||||
|
|
||||||
if not file_path:
|
if not file_path:
|
||||||
|
|
|
@ -68,8 +68,8 @@ def wallets(default_wallet, temp_directory, cluster: Cluster) -> Wallets:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def file_path():
|
def file_path(simple_object_size):
|
||||||
yield generate_file()
|
yield generate_file(simple_object_size)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Optional
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster_test_base import ClusterTestBase
|
from cluster_test_base import ClusterTestBase
|
||||||
from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, FREE_STORAGE, SIMPLE_OBJ_SIZE, WALLET_PASS
|
from common import ASSETS_DIR, FREE_STORAGE, WALLET_PASS
|
||||||
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.utils.wallet import init_wallet
|
from neofs_testlib.utils.wallet import init_wallet
|
||||||
|
@ -37,7 +37,7 @@ deposit = 30
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
|
@ -68,7 +68,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group in Private Container")
|
@allure.title("Test Storage Group in Private Container")
|
||||||
def test_storagegroup_basic_private_container(self, object_size):
|
def test_storagegroup_basic_private_container(self, object_size, max_object_size):
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
self.main_wallet, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint
|
self.main_wallet, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint
|
||||||
)
|
)
|
||||||
|
@ -88,6 +88,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
)
|
)
|
||||||
self.expect_failure_for_storagegroup_operations(
|
self.expect_failure_for_storagegroup_operations(
|
||||||
wallet=self.other_wallet,
|
wallet=self.other_wallet,
|
||||||
|
@ -103,7 +104,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group in Public Container")
|
@allure.title("Test Storage Group in Public Container")
|
||||||
def test_storagegroup_basic_public_container(self, object_size):
|
def test_storagegroup_basic_public_container(self, object_size, max_object_size):
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
self.main_wallet,
|
self.main_wallet,
|
||||||
basic_acl="public-read-write",
|
basic_acl="public-read-write",
|
||||||
|
@ -120,12 +121,14 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
)
|
)
|
||||||
self.expect_success_for_storagegroup_operations(
|
self.expect_success_for_storagegroup_operations(
|
||||||
wallet=self.other_wallet,
|
wallet=self.other_wallet,
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
)
|
)
|
||||||
self.storagegroup_operations_by_system_ro_container(
|
self.storagegroup_operations_by_system_ro_container(
|
||||||
wallet=self.main_wallet,
|
wallet=self.main_wallet,
|
||||||
|
@ -135,7 +138,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@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, object_size):
|
def test_storagegroup_basic_ro_container(self, object_size, max_object_size):
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
self.main_wallet,
|
self.main_wallet,
|
||||||
basic_acl="public-read",
|
basic_acl="public-read",
|
||||||
|
@ -152,6 +155,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
)
|
)
|
||||||
self.storagegroup_operations_by_other_ro_container(
|
self.storagegroup_operations_by_other_ro_container(
|
||||||
owner_wallet=self.main_wallet,
|
owner_wallet=self.main_wallet,
|
||||||
|
@ -168,7 +172,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Storage Group with Bearer Allow")
|
@allure.title("Test Storage Group with Bearer Allow")
|
||||||
def test_storagegroup_bearer_allow(self, object_size):
|
def test_storagegroup_bearer_allow(self, object_size, max_object_size):
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
self.main_wallet,
|
self.main_wallet,
|
||||||
basic_acl="eacl-public-read-write",
|
basic_acl="eacl-public-read-write",
|
||||||
|
@ -185,6 +189,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
)
|
)
|
||||||
storage_group = put_storagegroup(
|
storage_group = put_storagegroup(
|
||||||
self.shell, self.cluster.default_rpc_endpoint, self.main_wallet, cid, objects
|
self.shell, self.cluster.default_rpc_endpoint, self.main_wallet, cid, objects
|
||||||
|
@ -219,6 +224,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
cid=cid,
|
cid=cid,
|
||||||
obj_list=objects,
|
obj_list=objects,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
bearer=bearer_file,
|
bearer=bearer_file,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -259,6 +265,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
cid: str,
|
cid: str,
|
||||||
obj_list: list,
|
obj_list: list,
|
||||||
object_size: int,
|
object_size: int,
|
||||||
|
max_object_size: int,
|
||||||
bearer: Optional[str] = None,
|
bearer: Optional[str] = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -285,6 +292,7 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
gid=storage_group,
|
gid=storage_group,
|
||||||
obj_list=obj_list,
|
obj_list=obj_list,
|
||||||
object_size=object_size,
|
object_size=object_size,
|
||||||
|
max_object_size=max_object_size,
|
||||||
bearer=bearer,
|
bearer=bearer,
|
||||||
)
|
)
|
||||||
delete_storagegroup(
|
delete_storagegroup(
|
||||||
|
@ -381,7 +389,11 @@ class TestStorageGroup(ClusterTestBase):
|
||||||
|
|
||||||
@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(
|
||||||
self, wallet: str, cid: str, obj_list: list, object_size: int
|
self,
|
||||||
|
wallet: str,
|
||||||
|
cid: str,
|
||||||
|
obj_list: list,
|
||||||
|
object_size: int,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
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
|
||||||
|
|
|
@ -16,11 +16,14 @@ from common import (
|
||||||
BACKGROUND_OBJ_SIZE,
|
BACKGROUND_OBJ_SIZE,
|
||||||
BACKGROUND_READERS_COUNT,
|
BACKGROUND_READERS_COUNT,
|
||||||
BACKGROUND_WRITERS_COUNT,
|
BACKGROUND_WRITERS_COUNT,
|
||||||
|
COMPLEX_OBJECT_CHUNKS_COUNT,
|
||||||
|
COMPLEX_OBJECT_TAIL_SIZE,
|
||||||
FREE_STORAGE,
|
FREE_STORAGE,
|
||||||
HOSTING_CONFIG_FILE,
|
HOSTING_CONFIG_FILE,
|
||||||
LOAD_NODE_SSH_PRIVATE_KEY_PATH,
|
LOAD_NODE_SSH_PRIVATE_KEY_PATH,
|
||||||
LOAD_NODE_SSH_USER,
|
LOAD_NODE_SSH_USER,
|
||||||
LOAD_NODES,
|
LOAD_NODES,
|
||||||
|
SIMPLE_OBJECT_SIZE,
|
||||||
STORAGE_NODE_SERVICE_NAME_REGEX,
|
STORAGE_NODE_SERVICE_NAME_REGEX,
|
||||||
WALLET_PASS,
|
WALLET_PASS,
|
||||||
)
|
)
|
||||||
|
@ -32,6 +35,8 @@ 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.neofs_verbs import get_netmap_netinfo
|
||||||
from python_keywords.node_management import storage_node_healthcheck
|
from python_keywords.node_management import storage_node_healthcheck
|
||||||
|
|
||||||
from helpers.wallet import WalletFactory
|
from helpers.wallet import WalletFactory
|
||||||
|
@ -81,6 +86,28 @@ def require_multiple_hosts(hosting: Hosting):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def max_object_size(cluster: Cluster, client_shell: Shell) -> int:
|
||||||
|
storage_node = cluster.storage_nodes[0]
|
||||||
|
net_info = get_netmap_netinfo(
|
||||||
|
wallet=storage_node.get_wallet_path(),
|
||||||
|
wallet_config=storage_node.get_wallet_config_path(),
|
||||||
|
endpoint=storage_node.get_rpc_endpoint(),
|
||||||
|
shell=client_shell,
|
||||||
|
)
|
||||||
|
yield net_info["maximum_object_size"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def simple_object_size(max_object_size: int) -> int:
|
||||||
|
yield int(SIMPLE_OBJECT_SIZE) if int(SIMPLE_OBJECT_SIZE) < max_object_size else max_object_size
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def complex_object_size(max_object_size: int) -> int:
|
||||||
|
return max_object_size * int(COMPLEX_OBJECT_CHUNKS_COUNT) + int(COMPLEX_OBJECT_TAIL_SIZE)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def wallet_factory(temp_directory: str, client_shell: Shell, cluster: Cluster) -> WalletFactory:
|
def wallet_factory(temp_directory: str, client_shell: Shell, cluster: Cluster) -> WalletFactory:
|
||||||
return WalletFactory(temp_directory, client_shell, cluster)
|
return WalletFactory(temp_directory, client_shell, cluster)
|
||||||
|
|
|
@ -38,7 +38,9 @@ class TestFailoverNetwork(ClusterTestBase):
|
||||||
wait_all_storage_nodes_returned(self.cluster)
|
wait_all_storage_nodes_returned(self.cluster)
|
||||||
|
|
||||||
@allure.title("Block Storage node traffic")
|
@allure.title("Block Storage node traffic")
|
||||||
def test_block_storage_node_traffic(self, default_wallet, require_multiple_hosts):
|
def test_block_storage_node_traffic(
|
||||||
|
self, default_wallet, require_multiple_hosts, simple_object_size
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Block storage nodes traffic using iptables and wait for replication for objects.
|
Block storage nodes traffic using iptables and wait for replication for objects.
|
||||||
"""
|
"""
|
||||||
|
@ -47,7 +49,7 @@ class TestFailoverNetwork(ClusterTestBase):
|
||||||
wakeup_node_timeout = 10 # timeout to let nodes detect that traffic has blocked
|
wakeup_node_timeout = 10 # timeout to let nodes detect that traffic has blocked
|
||||||
nodes_to_block_count = 2
|
nodes_to_block_count = 2
|
||||||
|
|
||||||
source_file_path = generate_file()
|
source_file_path = generate_file(simple_object_size)
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
wallet,
|
wallet,
|
||||||
shell=self.shell,
|
shell=self.shell,
|
||||||
|
|
|
@ -47,14 +47,11 @@ class TestFailoverStorage(ClusterTestBase):
|
||||||
@pytest.mark.parametrize("hard_reboot", [True, False])
|
@pytest.mark.parametrize("hard_reboot", [True, False])
|
||||||
@pytest.mark.failover_reboot
|
@pytest.mark.failover_reboot
|
||||||
def test_lose_storage_node_host(
|
def test_lose_storage_node_host(
|
||||||
self,
|
self, default_wallet, hard_reboot: bool, require_multiple_hosts, simple_object_size
|
||||||
default_wallet,
|
|
||||||
hard_reboot: bool,
|
|
||||||
require_multiple_hosts,
|
|
||||||
):
|
):
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
placement_rule = "REP 2 IN X CBF 2 SELECT 2 FROM * AS X"
|
placement_rule = "REP 2 IN X CBF 2 SELECT 2 FROM * AS X"
|
||||||
source_file_path = generate_file()
|
source_file_path = generate_file(simple_object_size)
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
wallet,
|
wallet,
|
||||||
shell=self.shell,
|
shell=self.shell,
|
||||||
|
@ -106,14 +103,11 @@ class TestFailoverStorage(ClusterTestBase):
|
||||||
@pytest.mark.parametrize("sequence", [True, False])
|
@pytest.mark.parametrize("sequence", [True, False])
|
||||||
@pytest.mark.failover_panic
|
@pytest.mark.failover_panic
|
||||||
def test_panic_storage_node_host(
|
def test_panic_storage_node_host(
|
||||||
self,
|
self, default_wallet, require_multiple_hosts, sequence: bool, simple_object_size
|
||||||
default_wallet,
|
|
||||||
require_multiple_hosts,
|
|
||||||
sequence: bool,
|
|
||||||
):
|
):
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
placement_rule = "REP 2 IN X CBF 2 SELECT 2 FROM * AS X"
|
placement_rule = "REP 2 IN X CBF 2 SELECT 2 FROM * AS X"
|
||||||
source_file_path = generate_file()
|
source_file_path = generate_file(simple_object_size)
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
wallet,
|
wallet,
|
||||||
shell=self.shell,
|
shell=self.shell,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster import StorageNode
|
from cluster import StorageNode
|
||||||
from cluster_test_base import ClusterTestBase
|
from cluster_test_base import ClusterTestBase
|
||||||
from common import COMPLEX_OBJ_SIZE, MORPH_BLOCK_TIME, NEOFS_CONTRACT_CACHE_TIMEOUT
|
from common import MORPH_BLOCK_TIME, NEOFS_CONTRACT_CACHE_TIMEOUT
|
||||||
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_NOT_FOUND, error_matches_status
|
from grpc_responses import OBJECT_NOT_FOUND, error_matches_status
|
||||||
|
@ -49,9 +49,10 @@ check_nodes: list[StorageNode] = []
|
||||||
class TestNodeManagement(ClusterTestBase):
|
class TestNodeManagement(ClusterTestBase):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@allure.title("Create container and pick the node with data")
|
@allure.title("Create container and pick the node with data")
|
||||||
def create_container_and_pick_node(self, default_wallet: str) -> Tuple[str, StorageNode]:
|
def create_container_and_pick_node(
|
||||||
default_wallet
|
self, default_wallet: str, simple_object_size
|
||||||
file_path = generate_file()
|
) -> Tuple[str, StorageNode]:
|
||||||
|
file_path = generate_file(simple_object_size)
|
||||||
placement_rule = "REP 1 IN X CBF 1 SELECT 1 FROM * AS X"
|
placement_rule = "REP 1 IN X CBF 1 SELECT 1 FROM * AS X"
|
||||||
endpoint = self.cluster.default_rpc_endpoint
|
endpoint = self.cluster.default_rpc_endpoint
|
||||||
|
|
||||||
|
@ -126,6 +127,7 @@ class TestNodeManagement(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
default_wallet,
|
default_wallet,
|
||||||
return_nodes_after_test_run,
|
return_nodes_after_test_run,
|
||||||
|
simple_object_size,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
This test remove one node from cluster then add it back. Test uses base control operations with storage nodes (healthcheck, netmap-snapshot, set-status).
|
This test remove one node from cluster then add it back. Test uses base control operations with storage nodes (healthcheck, netmap-snapshot, set-status).
|
||||||
|
@ -133,7 +135,7 @@ class TestNodeManagement(ClusterTestBase):
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
placement_rule_3 = "REP 3 IN X CBF 1 SELECT 3 FROM * AS X"
|
placement_rule_3 = "REP 3 IN X CBF 1 SELECT 3 FROM * AS X"
|
||||||
placement_rule_4 = "REP 4 IN X CBF 1 SELECT 4 FROM * AS X"
|
placement_rule_4 = "REP 4 IN X CBF 1 SELECT 4 FROM * AS X"
|
||||||
source_file_path = generate_file()
|
source_file_path = generate_file(simple_object_size)
|
||||||
|
|
||||||
storage_nodes = self.cluster.storage_nodes
|
storage_nodes = self.cluster.storage_nodes
|
||||||
random_node = random.choice(storage_nodes[1:])
|
random_node = random.choice(storage_nodes[1:])
|
||||||
|
@ -219,12 +221,14 @@ class TestNodeManagement(ClusterTestBase):
|
||||||
)
|
)
|
||||||
@pytest.mark.node_mgmt
|
@pytest.mark.node_mgmt
|
||||||
@allure.title("Test object copies based on placement policy")
|
@allure.title("Test object copies based on placement policy")
|
||||||
def test_placement_policy(self, default_wallet, placement_rule, expected_copies):
|
def test_placement_policy(
|
||||||
|
self, default_wallet, placement_rule, expected_copies, simple_object_size
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
This test checks object's copies based on container's placement policy.
|
This test checks object's copies based on container's placement policy.
|
||||||
"""
|
"""
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
self.validate_object_copies(wallet, placement_rule, file_path, expected_copies)
|
self.validate_object_copies(wallet, placement_rule, file_path, expected_copies)
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -279,14 +283,19 @@ class TestNodeManagement(ClusterTestBase):
|
||||||
@pytest.mark.node_mgmt
|
@pytest.mark.node_mgmt
|
||||||
@allure.title("Test object copies and storage nodes based on placement policy")
|
@allure.title("Test object copies and storage nodes based on placement policy")
|
||||||
def test_placement_policy_with_nodes(
|
def test_placement_policy_with_nodes(
|
||||||
self, default_wallet, placement_rule, expected_copies, expected_nodes_id: set[int]
|
self,
|
||||||
|
default_wallet,
|
||||||
|
placement_rule,
|
||||||
|
expected_copies,
|
||||||
|
expected_nodes_id: set[int],
|
||||||
|
simple_object_size,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Based on container's placement policy check that storage nodes are piked correctly and object has
|
Based on container's placement policy check that storage nodes are piked correctly and object has
|
||||||
correct copies amount.
|
correct copies amount.
|
||||||
"""
|
"""
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
cid, oid, found_nodes = self.validate_object_copies(
|
cid, oid, found_nodes = self.validate_object_copies(
|
||||||
wallet, placement_rule, file_path, expected_copies
|
wallet, placement_rule, file_path, expected_copies
|
||||||
)
|
)
|
||||||
|
@ -303,24 +312,28 @@ class TestNodeManagement(ClusterTestBase):
|
||||||
)
|
)
|
||||||
@pytest.mark.node_mgmt
|
@pytest.mark.node_mgmt
|
||||||
@allure.title("Negative cases for placement policy")
|
@allure.title("Negative cases for placement policy")
|
||||||
def test_placement_policy_negative(self, default_wallet, placement_rule, expected_copies):
|
def test_placement_policy_negative(
|
||||||
|
self, default_wallet, placement_rule, expected_copies, simple_object_size
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Negative test for placement policy.
|
Negative test for placement policy.
|
||||||
"""
|
"""
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
with pytest.raises(RuntimeError, match=".*not enough nodes to SELECT from.*"):
|
with pytest.raises(RuntimeError, match=".*not enough nodes to SELECT from.*"):
|
||||||
self.validate_object_copies(wallet, placement_rule, file_path, expected_copies)
|
self.validate_object_copies(wallet, placement_rule, file_path, expected_copies)
|
||||||
|
|
||||||
@pytest.mark.node_mgmt
|
@pytest.mark.node_mgmt
|
||||||
@allure.title("NeoFS object could be dropped using control command")
|
@allure.title("NeoFS object could be dropped using control command")
|
||||||
def test_drop_object(self, default_wallet):
|
def test_drop_object(self, default_wallet, complex_object_size, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test checks object could be dropped using `neofs-cli control drop-objects` command.
|
Test checks object could be dropped using `neofs-cli control drop-objects` command.
|
||||||
"""
|
"""
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
endpoint = self.cluster.default_rpc_endpoint
|
endpoint = self.cluster.default_rpc_endpoint
|
||||||
file_path_simple, file_path_complex = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_complex = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
|
|
||||||
locode = get_locode_from_random_node(self.cluster)
|
locode = get_locode_from_random_node(self.cluster)
|
||||||
rule = f"REP 1 CBF 1 SELECT 1 FROM * FILTER 'UN-LOCODE' EQ '{locode}' AS LOC"
|
rule = f"REP 1 CBF 1 SELECT 1 FROM * FILTER 'UN-LOCODE' EQ '{locode}' AS LOC"
|
||||||
|
@ -358,9 +371,10 @@ class TestNodeManagement(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
default_wallet,
|
default_wallet,
|
||||||
create_container_and_pick_node,
|
create_container_and_pick_node,
|
||||||
|
simple_object_size,
|
||||||
):
|
):
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
|
|
||||||
cid, node = create_container_and_pick_node
|
cid, node = create_container_and_pick_node
|
||||||
original_oid = put_object_to_random_node(wallet, file_path, cid, self.shell, self.cluster)
|
original_oid = put_object_to_random_node(wallet, file_path, cid, self.shell, self.cluster)
|
||||||
|
|
|
@ -5,14 +5,12 @@ import sys
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster import Cluster
|
from cluster import Cluster
|
||||||
from common import COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE
|
|
||||||
from container import create_container
|
|
||||||
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 OUT_OF_RANGE
|
from grpc_responses import OUT_OF_RANGE
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from pytest import FixtureRequest
|
from pytest import FixtureRequest
|
||||||
|
from python_keywords.container import create_container
|
||||||
from python_keywords.neofs_verbs import (
|
from python_keywords.neofs_verbs import (
|
||||||
get_netmap_netinfo,
|
|
||||||
get_object_from_random_node,
|
get_object_from_random_node,
|
||||||
get_range,
|
get_range,
|
||||||
get_range_hash,
|
get_range_hash,
|
||||||
|
@ -42,10 +40,7 @@ RANGES_COUNT = 4 # by quarters
|
||||||
RANGE_MIN_LEN = 10
|
RANGE_MIN_LEN = 10
|
||||||
RANGE_MAX_LEN = 500
|
RANGE_MAX_LEN = 500
|
||||||
# Used for static ranges found with issues
|
# Used for static ranges found with issues
|
||||||
STATIC_RANGES = {
|
STATIC_RANGES = {}
|
||||||
SIMPLE_OBJ_SIZE: [],
|
|
||||||
COMPLEX_OBJ_SIZE: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def generate_ranges(file_size: int, max_object_size: int) -> list[(int, int)]:
|
def generate_ranges(file_size: int, max_object_size: int) -> list[(int, int)]:
|
||||||
|
@ -58,10 +53,10 @@ def generate_ranges(file_size: int, max_object_size: int) -> list[(int, int)]:
|
||||||
file_ranges.append((int(file_range_step * i), int(file_range_step * (i + 1))))
|
file_ranges.append((int(file_range_step * i), int(file_range_step * (i + 1))))
|
||||||
|
|
||||||
# For simple object we can read all file ranges without too much time for testing
|
# For simple object we can read all file ranges without too much time for testing
|
||||||
if file_size == SIMPLE_OBJ_SIZE:
|
if file_size < max_object_size:
|
||||||
file_ranges_to_test.extend(file_ranges)
|
file_ranges_to_test.extend(file_ranges)
|
||||||
# For complex object we need to fetch multiple child objects from different nodes.
|
# For complex object we need to fetch multiple child objects from different nodes.
|
||||||
if file_size == COMPLEX_OBJ_SIZE:
|
else:
|
||||||
assert (
|
assert (
|
||||||
file_size >= RANGE_MAX_LEN + max_object_size
|
file_size >= RANGE_MAX_LEN + max_object_size
|
||||||
), f"Complex object size should be at least {max_object_size + RANGE_MAX_LEN}. Current: {file_size}"
|
), f"Complex object size should be at least {max_object_size + RANGE_MAX_LEN}. Current: {file_size}"
|
||||||
|
@ -83,7 +78,7 @@ def generate_ranges(file_size: int, max_object_size: int) -> list[(int, int)]:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
params=[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
params=[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
# Scope session to upload/delete each files set only once
|
# Scope session to upload/delete each files set only once
|
||||||
scope="module",
|
scope="module",
|
||||||
|
@ -132,7 +127,7 @@ def storage_objects(
|
||||||
class TestObjectApi(ClusterTestBase):
|
class TestObjectApi(ClusterTestBase):
|
||||||
@allure.title("Validate object storage policy by native API")
|
@allure.title("Validate object storage policy by native API")
|
||||||
def test_object_storage_policies(
|
def test_object_storage_policies(
|
||||||
self, request: FixtureRequest, storage_objects: list[StorageObjectInfo]
|
self, request: FixtureRequest, storage_objects: list[StorageObjectInfo], simple_object_size
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Validate object storage policy
|
Validate object storage policy
|
||||||
|
@ -143,7 +138,7 @@ class TestObjectApi(ClusterTestBase):
|
||||||
|
|
||||||
with allure.step("Validate storage policy for objects"):
|
with allure.step("Validate storage policy for objects"):
|
||||||
for storage_object in storage_objects:
|
for storage_object in storage_objects:
|
||||||
if storage_object.size == SIMPLE_OBJ_SIZE:
|
if storage_object.size == simple_object_size:
|
||||||
copies = get_simple_object_copies(
|
copies = get_simple_object_copies(
|
||||||
storage_object.wallet_file_path,
|
storage_object.wallet_file_path,
|
||||||
storage_object.cid,
|
storage_object.cid,
|
||||||
|
@ -257,7 +252,9 @@ class TestObjectApi(ClusterTestBase):
|
||||||
|
|
||||||
@allure.title("Validate object search with removed items")
|
@allure.title("Validate object search with removed items")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
"object_size",
|
||||||
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_object_search_should_return_tombstone_items(
|
def test_object_search_should_return_tombstone_items(
|
||||||
self, default_wallet: str, request: FixtureRequest, object_size: int
|
self, default_wallet: str, request: FixtureRequest, object_size: int
|
||||||
|
@ -330,7 +327,7 @@ class TestObjectApi(ClusterTestBase):
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
@pytest.mark.grpc_api
|
@pytest.mark.grpc_api
|
||||||
def test_object_get_range_hash(
|
def test_object_get_range_hash(
|
||||||
self, request: FixtureRequest, storage_objects: list[StorageObjectInfo]
|
self, request: FixtureRequest, storage_objects: list[StorageObjectInfo], max_object_size
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Validate get_range_hash for object by common gRPC API
|
Validate get_range_hash for object by common gRPC API
|
||||||
|
@ -343,10 +340,6 @@ class TestObjectApi(ClusterTestBase):
|
||||||
cid = storage_objects[0].cid
|
cid = storage_objects[0].cid
|
||||||
oids = [storage_object.oid for storage_object in storage_objects[:2]]
|
oids = [storage_object.oid for storage_object in storage_objects[:2]]
|
||||||
file_path = storage_objects[0].file_path
|
file_path = storage_objects[0].file_path
|
||||||
net_info = get_netmap_netinfo(
|
|
||||||
wallet, self.shell, endpoint=self.cluster.default_rpc_endpoint
|
|
||||||
)
|
|
||||||
max_object_size = net_info["maximum_object_size"]
|
|
||||||
|
|
||||||
file_ranges_to_test = generate_ranges(storage_objects[0].size, max_object_size)
|
file_ranges_to_test = generate_ranges(storage_objects[0].size, max_object_size)
|
||||||
logging.info(f"Ranges used in test {file_ranges_to_test}")
|
logging.info(f"Ranges used in test {file_ranges_to_test}")
|
||||||
|
@ -372,7 +365,7 @@ class TestObjectApi(ClusterTestBase):
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
@pytest.mark.grpc_api
|
@pytest.mark.grpc_api
|
||||||
def test_object_get_range(
|
def test_object_get_range(
|
||||||
self, request: FixtureRequest, storage_objects: list[StorageObjectInfo]
|
self, request: FixtureRequest, storage_objects: list[StorageObjectInfo], max_object_size
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Validate get_range for object by common gRPC API
|
Validate get_range for object by common gRPC API
|
||||||
|
@ -383,10 +376,6 @@ class TestObjectApi(ClusterTestBase):
|
||||||
cid = storage_objects[0].cid
|
cid = storage_objects[0].cid
|
||||||
oids = [storage_object.oid for storage_object in storage_objects[:2]]
|
oids = [storage_object.oid for storage_object in storage_objects[:2]]
|
||||||
file_path = storage_objects[0].file_path
|
file_path = storage_objects[0].file_path
|
||||||
net_info = get_netmap_netinfo(
|
|
||||||
wallet, self.shell, endpoint=self.cluster.default_rpc_endpoint
|
|
||||||
)
|
|
||||||
max_object_size = net_info["maximum_object_size"]
|
|
||||||
|
|
||||||
file_ranges_to_test = generate_ranges(storage_objects[0].size, max_object_size)
|
file_ranges_to_test = generate_ranges(storage_objects[0].size, max_object_size)
|
||||||
logging.info(f"Ranges used in test {file_ranges_to_test}")
|
logging.info(f"Ranges used in test {file_ranges_to_test}")
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster import Cluster
|
from cluster import Cluster
|
||||||
from common import COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE
|
|
||||||
from container import REP_2_FOR_3_NODES_PLACEMENT_RULE, SINGLE_PLACEMENT_RULE, create_container
|
from container import REP_2_FOR_3_NODES_PLACEMENT_RULE, SINGLE_PLACEMENT_RULE, create_container
|
||||||
from epoch import get_epoch
|
from epoch import get_epoch
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
|
@ -88,7 +87,7 @@ class TestObjectApiWithBearerToken(ClusterTestBase):
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"storage_objects",
|
"storage_objects",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
|
@ -99,7 +98,8 @@ class TestObjectApiWithBearerToken(ClusterTestBase):
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
allure.dynamic.title(
|
allure.dynamic.title(
|
||||||
f"Check that objects can be deleted from any node using s3gate wallet with bearer token for {request.node.callspec.id}"
|
f"Check that objects can be deleted from any node using s3gate wallet with bearer "
|
||||||
|
f"token for {request.node.callspec.id}"
|
||||||
)
|
)
|
||||||
|
|
||||||
s3_gate_wallet = self.cluster.s3gates[0]
|
s3_gate_wallet = self.cluster.s3gates[0]
|
||||||
|
@ -124,7 +124,7 @@ class TestObjectApiWithBearerToken(ClusterTestBase):
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"file_size",
|
"file_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_get_object_with_s3_wallet_bearer_from_all_nodes(
|
def test_get_object_with_s3_wallet_bearer_from_all_nodes(
|
||||||
|
@ -135,7 +135,8 @@ class TestObjectApiWithBearerToken(ClusterTestBase):
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
allure.dynamic.title(
|
allure.dynamic.title(
|
||||||
f"Check that objects can be deleted from any node using s3gate wallet with bearer token for {request.node.callspec.id}"
|
"Check that objects can be deleted from any node using s3gate wallet with bearer "
|
||||||
|
f"token for {request.node.callspec.id}"
|
||||||
)
|
)
|
||||||
|
|
||||||
s3_gate_wallet = self.cluster.s3gates[0]
|
s3_gate_wallet = self.cluster.s3gates[0]
|
||||||
|
|
|
@ -2,12 +2,11 @@ import logging
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from common import COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE
|
|
||||||
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 pytest import FixtureRequest
|
from pytest import FixtureRequest
|
||||||
|
from python_keywords.container import create_container
|
||||||
from python_keywords.neofs_verbs import get_object_from_random_node, put_object_to_random_node
|
from python_keywords.neofs_verbs import get_object_from_random_node, put_object_to_random_node
|
||||||
from utility import wait_for_gc_pass_on_storage_nodes
|
from utility import wait_for_gc_pass_on_storage_nodes
|
||||||
|
|
||||||
|
@ -21,7 +20,9 @@ logger = logging.getLogger("NeoLogger")
|
||||||
class ObjectApiLifetimeTest(ClusterTestBase):
|
class ObjectApiLifetimeTest(ClusterTestBase):
|
||||||
@allure.title("Test object life time")
|
@allure.title("Test object life time")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
"object_size",
|
||||||
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_object_api_lifetime(
|
def test_object_api_lifetime(
|
||||||
self, default_wallet: str, request: FixtureRequest, object_size: int
|
self, default_wallet: str, request: FixtureRequest, object_size: int
|
||||||
|
|
|
@ -5,9 +5,8 @@ import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster import Cluster
|
from cluster import Cluster
|
||||||
from cluster_test_base import ClusterTestBase
|
from cluster_test_base import ClusterTestBase
|
||||||
from common import COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE, STORAGE_GC_TIME
|
from common import STORAGE_GC_TIME
|
||||||
from complex_object_actions import get_link_object
|
from complex_object_actions import get_link_object
|
||||||
from container import create_container
|
|
||||||
from epoch import ensure_fresh_epoch, get_epoch, tick_epoch
|
from epoch import ensure_fresh_epoch, get_epoch, tick_epoch
|
||||||
from grpc_responses import (
|
from grpc_responses import (
|
||||||
LIFETIME_REQUIRED,
|
LIFETIME_REQUIRED,
|
||||||
|
@ -20,6 +19,7 @@ from grpc_responses import (
|
||||||
)
|
)
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
from pytest import FixtureRequest
|
from pytest import FixtureRequest
|
||||||
|
from python_keywords.container import create_container
|
||||||
from python_keywords.neofs_verbs import delete_object, head_object, lock_object
|
from python_keywords.neofs_verbs import delete_object, head_object, lock_object
|
||||||
from test_control import expect_not_raises, wait_for_success
|
from test_control import expect_not_raises, wait_for_success
|
||||||
from utility import parse_time, wait_for_gc_pass_on_storage_nodes
|
from utility import parse_time, wait_for_gc_pass_on_storage_nodes
|
||||||
|
@ -143,7 +143,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@allure.title("Locked object should be protected from deletion")
|
@allure.title("Locked object should be protected from deletion")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"locked_storage_object",
|
"locked_storage_object",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
|
@ -170,7 +170,9 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
|
|
||||||
@allure.title("Lock object itself should be protected from deletion")
|
@allure.title("Lock object itself should be protected from deletion")
|
||||||
# We operate with only lock object here so no complex object needed in this test
|
# We operate with only lock object here so no complex object needed in this test
|
||||||
@pytest.mark.parametrize("locked_storage_object", [SIMPLE_OBJ_SIZE], indirect=True)
|
@pytest.mark.parametrize(
|
||||||
|
"locked_storage_object", [pytest.lazy_fixture("simple_object_size")], indirect=True
|
||||||
|
)
|
||||||
def test_lock_object_itself_cannot_be_deleted(
|
def test_lock_object_itself_cannot_be_deleted(
|
||||||
self,
|
self,
|
||||||
locked_storage_object: StorageObjectInfo,
|
locked_storage_object: StorageObjectInfo,
|
||||||
|
@ -193,7 +195,9 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
|
|
||||||
@allure.title("Lock object itself cannot be locked")
|
@allure.title("Lock object itself cannot be locked")
|
||||||
# We operate with only lock object here so no complex object needed in this test
|
# We operate with only lock object here so no complex object needed in this test
|
||||||
@pytest.mark.parametrize("locked_storage_object", [SIMPLE_OBJ_SIZE], indirect=True)
|
@pytest.mark.parametrize(
|
||||||
|
"locked_storage_object", [pytest.lazy_fixture("simple_object_size")], indirect=True
|
||||||
|
)
|
||||||
def test_lock_object_cannot_be_locked(
|
def test_lock_object_cannot_be_locked(
|
||||||
self,
|
self,
|
||||||
locked_storage_object: StorageObjectInfo,
|
locked_storage_object: StorageObjectInfo,
|
||||||
|
@ -217,7 +221,9 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
|
|
||||||
@allure.title("Cannot lock object without lifetime and expire_at fields")
|
@allure.title("Cannot lock object without lifetime and expire_at fields")
|
||||||
# We operate with only lock object here so no complex object needed in this test
|
# We operate with only lock object here so no complex object needed in this test
|
||||||
@pytest.mark.parametrize("locked_storage_object", [SIMPLE_OBJ_SIZE], indirect=True)
|
@pytest.mark.parametrize(
|
||||||
|
"locked_storage_object", [pytest.lazy_fixture("simple_object_size")], indirect=True
|
||||||
|
)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"wrong_lifetime,wrong_expire_at,expected_error",
|
"wrong_lifetime,wrong_expire_at,expected_error",
|
||||||
[
|
[
|
||||||
|
@ -259,7 +265,9 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
|
|
||||||
@allure.title("Expired object should be deleted after locks are expired")
|
@allure.title("Expired object should be deleted after locks are expired")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size", [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"]
|
"object_size",
|
||||||
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_expired_object_should_be_deleted_after_locks_are_expired(
|
def test_expired_object_should_be_deleted_after_locks_are_expired(
|
||||||
self,
|
self,
|
||||||
|
@ -327,7 +335,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@allure.title("Should be possible to lock multiple objects at once")
|
@allure.title("Should be possible to lock multiple objects at once")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_should_be_possible_to_lock_multiple_objects_at_once(
|
def test_should_be_possible_to_lock_multiple_objects_at_once(
|
||||||
|
@ -382,7 +390,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@allure.title("Already outdated lock should not be applied")
|
@allure.title("Already outdated lock should not be applied")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_already_outdated_lock_should_not_be_applied(
|
def test_already_outdated_lock_should_not_be_applied(
|
||||||
|
@ -421,7 +429,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@allure.title("After lock expiration with lifetime user should be able to delete object")
|
@allure.title("After lock expiration with lifetime user should be able to delete object")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
@expect_not_raises()
|
@expect_not_raises()
|
||||||
|
@ -463,7 +471,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@allure.title("After lock expiration with expire_at user should be able to delete object")
|
@allure.title("After lock expiration with expire_at user should be able to delete object")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
@expect_not_raises()
|
@expect_not_raises()
|
||||||
|
@ -508,7 +516,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
# Only complex objects are required for this test
|
# Only complex objects are required for this test
|
||||||
"locked_storage_object",
|
"locked_storage_object",
|
||||||
[COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("complex_object_size")],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
def test_complex_object_chunks_should_also_be_protected_from_deletion(
|
def test_complex_object_chunks_should_also_be_protected_from_deletion(
|
||||||
|
@ -535,7 +543,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
# Only complex objects are required for this test
|
# Only complex objects are required for this test
|
||||||
"locked_storage_object",
|
"locked_storage_object",
|
||||||
[COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("complex_object_size")],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
def test_link_object_of_complex_object_should_also_be_protected_from_deletion(
|
def test_link_object_of_complex_object_should_also_be_protected_from_deletion(
|
||||||
|
|
|
@ -17,8 +17,8 @@ def pytest_generate_tests(metafunc):
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
class TestS3GateACL(TestS3GateBase):
|
class TestS3GateACL(TestS3GateBase):
|
||||||
@allure.title("Test S3: Object ACL")
|
@allure.title("Test S3: Object ACL")
|
||||||
def test_s3_object_ACL(self, bucket):
|
def test_s3_object_ACL(self, bucket, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
|
|
||||||
with allure.step("Put object into bucket, Check ACL is empty"):
|
with allure.step("Put object into bucket, Check ACL is empty"):
|
||||||
|
|
|
@ -103,8 +103,8 @@ class TestS3GateBucket(TestS3GateBase):
|
||||||
], "Permission for CanonicalUser is FULL_CONTROL"
|
], "Permission for CanonicalUser is FULL_CONTROL"
|
||||||
|
|
||||||
@allure.title("Test S3: create bucket with object lock")
|
@allure.title("Test S3: create bucket with object lock")
|
||||||
def test_s3_bucket_object_lock(self):
|
def test_s3_bucket_object_lock(self, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
|
|
||||||
with allure.step("Create bucket with --no-object-lock-enabled-for-bucket"):
|
with allure.step("Create bucket with --no-object-lock-enabled-for-bucket"):
|
||||||
|
@ -138,10 +138,10 @@ class TestS3GateBucket(TestS3GateBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test S3: delete bucket")
|
@allure.title("Test S3: delete bucket")
|
||||||
def test_s3_delete_bucket(self):
|
def test_s3_delete_bucket(self, simple_object_size):
|
||||||
file_path_1 = generate_file()
|
file_path_1 = generate_file(simple_object_size)
|
||||||
file_name_1 = object_key_from_file_path(file_path_1)
|
file_name_1 = object_key_from_file_path(file_path_1)
|
||||||
file_path_2 = generate_file()
|
file_path_2 = generate_file(simple_object_size)
|
||||||
file_name_2 = object_key_from_file_path(file_path_2)
|
file_name_2 = object_key_from_file_path(file_path_2)
|
||||||
bucket = s3_gate_bucket.create_bucket_s3(self.s3_client)
|
bucket = s3_gate_bucket.create_bucket_s3(self.s3_client)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ from random import choice, choices
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from aws_cli_client import AwsCliClient
|
from aws_cli_client import AwsCliClient
|
||||||
from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE
|
from common import ASSETS_DIR
|
||||||
from epoch import tick_epoch
|
from epoch import tick_epoch
|
||||||
from file_helper import (
|
from file_helper import (
|
||||||
generate_file,
|
generate_file,
|
||||||
|
@ -39,12 +39,12 @@ def pytest_generate_tests(metafunc):
|
||||||
@pytest.mark.s3_gate_base
|
@pytest.mark.s3_gate_base
|
||||||
class TestS3Gate(TestS3GateBase):
|
class TestS3Gate(TestS3GateBase):
|
||||||
@allure.title("Test S3 Bucket API")
|
@allure.title("Test S3 Bucket API")
|
||||||
def test_s3_buckets(self):
|
def test_s3_buckets(self, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test base S3 Bucket API (Create/List/Head/Delete).
|
Test base S3 Bucket API (Create/List/Head/Delete).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
|
|
||||||
with allure.step("Create buckets"):
|
with allure.step("Create buckets"):
|
||||||
|
@ -109,11 +109,13 @@ class TestS3Gate(TestS3GateBase):
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"file_type", ["simple", "large"], ids=["Simple object", "Large object"]
|
"file_type", ["simple", "large"], ids=["Simple object", "Large object"]
|
||||||
)
|
)
|
||||||
def test_s3_api_object(self, file_type, two_buckets):
|
def test_s3_api_object(self, file_type, two_buckets, simple_object_size, complex_object_size):
|
||||||
"""
|
"""
|
||||||
Test base S3 Object API (Put/Head/List) for simple and large objects.
|
Test base S3 Object API (Put/Head/List) for simple and large objects.
|
||||||
"""
|
"""
|
||||||
file_path = generate_file(SIMPLE_OBJ_SIZE if file_type == "simple" else COMPLEX_OBJ_SIZE)
|
file_path = generate_file(
|
||||||
|
simple_object_size if file_type == "simple" else complex_object_size
|
||||||
|
)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
|
|
||||||
bucket_1, bucket_2 = two_buckets
|
bucket_1, bucket_2 = two_buckets
|
||||||
|
@ -136,7 +138,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
s3_gate_object.get_object_attributes(self.s3_client, bucket, file_name, *attrs)
|
s3_gate_object.get_object_attributes(self.s3_client, bucket, file_name, *attrs)
|
||||||
|
|
||||||
@allure.title("Test S3 Sync directory")
|
@allure.title("Test S3 Sync directory")
|
||||||
def test_s3_sync_dir(self, bucket):
|
def test_s3_sync_dir(self, bucket, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test checks sync directory with AWS CLI utility.
|
Test checks sync directory with AWS CLI utility.
|
||||||
"""
|
"""
|
||||||
|
@ -147,8 +149,8 @@ class TestS3Gate(TestS3GateBase):
|
||||||
if not isinstance(self.s3_client, AwsCliClient):
|
if not isinstance(self.s3_client, AwsCliClient):
|
||||||
pytest.skip("This test is not supported with boto3 client")
|
pytest.skip("This test is not supported with boto3 client")
|
||||||
|
|
||||||
generate_file_with_content(file_path=file_path_1)
|
generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
generate_file_with_content(file_path=file_path_2)
|
generate_file_with_content(simple_object_size, file_path=file_path_2)
|
||||||
|
|
||||||
self.s3_client.sync(bucket_name=bucket, dir_path=os.path.dirname(file_path_1))
|
self.s3_client.sync(bucket_name=bucket, dir_path=os.path.dirname(file_path_1))
|
||||||
|
|
||||||
|
@ -166,19 +168,21 @@ class TestS3Gate(TestS3GateBase):
|
||||||
), "Expected hashes are the same"
|
), "Expected hashes are the same"
|
||||||
|
|
||||||
@allure.title("Test S3 Object versioning")
|
@allure.title("Test S3 Object versioning")
|
||||||
def test_s3_api_versioning(self, bucket):
|
def test_s3_api_versioning(self, bucket, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test checks basic versioning functionality for S3 bucket.
|
Test checks basic versioning functionality for S3 bucket.
|
||||||
"""
|
"""
|
||||||
version_1_content = "Version 1"
|
version_1_content = "Version 1"
|
||||||
version_2_content = "Version 2"
|
version_2_content = "Version 2"
|
||||||
file_name_simple = generate_file_with_content(content=version_1_content)
|
file_name_simple = generate_file_with_content(simple_object_size, content=version_1_content)
|
||||||
obj_key = os.path.basename(file_name_simple)
|
obj_key = os.path.basename(file_name_simple)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
||||||
generate_file_with_content(file_path=file_name_simple, content=version_2_content)
|
generate_file_with_content(
|
||||||
|
simple_object_size, file_path=file_name_simple, content=version_2_content
|
||||||
|
)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
||||||
|
|
||||||
with allure.step("Check bucket shows all versions"):
|
with allure.step("Check bucket shows all versions"):
|
||||||
|
@ -246,13 +250,15 @@ class TestS3Gate(TestS3GateBase):
|
||||||
|
|
||||||
@pytest.mark.s3_gate_multipart
|
@pytest.mark.s3_gate_multipart
|
||||||
@allure.title("Test S3 Object Multipart API")
|
@allure.title("Test S3 Object Multipart API")
|
||||||
def test_s3_api_multipart(self, bucket):
|
def test_s3_api_multipart(self, bucket, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test checks S3 Multipart API (Create multipart upload/Abort multipart upload/List multipart upload/
|
Test checks S3 Multipart API (Create multipart upload/Abort multipart upload/List multipart upload/
|
||||||
Upload part/List parts/Complete multipart upload).
|
Upload part/List parts/Complete multipart upload).
|
||||||
"""
|
"""
|
||||||
parts_count = 3
|
parts_count = 3
|
||||||
file_name_large = generate_file(SIMPLE_OBJ_SIZE * 1024 * 6 * parts_count) # 5Mb - min part
|
file_name_large = generate_file(
|
||||||
|
simple_object_size * 1024 * 6 * parts_count
|
||||||
|
) # 5Mb - min part
|
||||||
object_key = self.object_key_from_file_path(file_name_large)
|
object_key = self.object_key_from_file_path(file_name_large)
|
||||||
part_files = split_file(file_name_large, parts_count)
|
part_files = split_file(file_name_large, parts_count)
|
||||||
parts = []
|
parts = []
|
||||||
|
@ -320,7 +326,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
check_tags_by_bucket(self.s3_client, bucket, [])
|
check_tags_by_bucket(self.s3_client, bucket, [])
|
||||||
|
|
||||||
@allure.title("Test S3 Object tagging API")
|
@allure.title("Test S3 Object tagging API")
|
||||||
def test_s3_api_object_tagging(self, bucket):
|
def test_s3_api_object_tagging(self, bucket, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test checks S3 Object tagging API (Put tag/Get tag/Update tag).
|
Test checks S3 Object tagging API (Put tag/Get tag/Update tag).
|
||||||
"""
|
"""
|
||||||
|
@ -330,7 +336,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
("some-key--obj2", "some-value--obj2"),
|
("some-key--obj2", "some-value--obj2"),
|
||||||
]
|
]
|
||||||
key_value_pair_obj_new = [("some-key-obj-new", "some-value-obj-new")]
|
key_value_pair_obj_new = [("some-key-obj-new", "some-value-obj-new")]
|
||||||
file_name_simple = generate_file(SIMPLE_OBJ_SIZE)
|
file_name_simple = generate_file(simple_object_size)
|
||||||
obj_key = self.object_key_from_file_path(file_name_simple)
|
obj_key = self.object_key_from_file_path(file_name_simple)
|
||||||
|
|
||||||
s3_gate_bucket.put_bucket_tagging(self.s3_client, bucket, key_value_pair_bucket)
|
s3_gate_bucket.put_bucket_tagging(self.s3_client, bucket, key_value_pair_bucket)
|
||||||
|
@ -350,7 +356,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
check_tags_by_object(self.s3_client, bucket, obj_key, [])
|
check_tags_by_object(self.s3_client, bucket, obj_key, [])
|
||||||
|
|
||||||
@allure.title("Test S3: Delete object & delete objects S3 API")
|
@allure.title("Test S3: Delete object & delete objects S3 API")
|
||||||
def test_s3_api_delete(self, two_buckets):
|
def test_s3_api_delete(self, two_buckets, simple_object_size, complex_object_size):
|
||||||
"""
|
"""
|
||||||
Check delete_object and delete_objects S3 API operation. From first bucket some objects deleted one by one.
|
Check delete_object and delete_objects S3 API operation. From first bucket some objects deleted one by one.
|
||||||
From second bucket some objects deleted all at once.
|
From second bucket some objects deleted all at once.
|
||||||
|
@ -359,7 +365,7 @@ class TestS3Gate(TestS3GateBase):
|
||||||
max_delete_objects = 17
|
max_delete_objects = 17
|
||||||
put_objects = []
|
put_objects = []
|
||||||
file_paths = []
|
file_paths = []
|
||||||
obj_sizes = [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE]
|
obj_sizes = [simple_object_size, complex_object_size]
|
||||||
|
|
||||||
bucket_1, bucket_2 = two_buckets
|
bucket_1, bucket_2 = two_buckets
|
||||||
|
|
||||||
|
@ -406,12 +412,14 @@ class TestS3Gate(TestS3GateBase):
|
||||||
try_to_get_objects_and_expect_error(self.s3_client, bucket_2, objects_to_delete_b2)
|
try_to_get_objects_and_expect_error(self.s3_client, bucket_2, objects_to_delete_b2)
|
||||||
|
|
||||||
@allure.title("Test S3: Copy object to the same bucket")
|
@allure.title("Test S3: Copy object to the same bucket")
|
||||||
def test_s3_copy_same_bucket(self, bucket):
|
def test_s3_copy_same_bucket(self, bucket, complex_object_size, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test object can be copied to the same bucket.
|
Test object can be copied to the same bucket.
|
||||||
#TODO: delete after test_s3_copy_object will be merge
|
#TODO: delete after test_s3_copy_object will be merge
|
||||||
"""
|
"""
|
||||||
file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_large = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
file_name_simple = self.object_key_from_file_path(file_path_simple)
|
file_name_simple = self.object_key_from_file_path(file_path_simple)
|
||||||
file_name_large = self.object_key_from_file_path(file_path_large)
|
file_name_large = self.object_key_from_file_path(file_path_large)
|
||||||
bucket_objects = [file_name_simple, file_name_large]
|
bucket_objects = [file_name_simple, file_name_large]
|
||||||
|
@ -448,12 +456,14 @@ class TestS3Gate(TestS3GateBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test S3: Copy object to another bucket")
|
@allure.title("Test S3: Copy object to another bucket")
|
||||||
def test_s3_copy_to_another_bucket(self, two_buckets):
|
def test_s3_copy_to_another_bucket(self, two_buckets, complex_object_size, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test object can be copied to another bucket.
|
Test object can be copied to another bucket.
|
||||||
#TODO: delete after test_s3_copy_object will be merge
|
#TODO: delete after test_s3_copy_object will be merge
|
||||||
"""
|
"""
|
||||||
file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_large = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
file_name_simple = self.object_key_from_file_path(file_path_simple)
|
file_name_simple = self.object_key_from_file_path(file_path_simple)
|
||||||
file_name_large = self.object_key_from_file_path(file_path_large)
|
file_name_large = self.object_key_from_file_path(file_path_large)
|
||||||
bucket_1_objects = [file_name_simple, file_name_large]
|
bucket_1_objects = [file_name_simple, file_name_large]
|
||||||
|
|
|
@ -21,8 +21,8 @@ def pytest_generate_tests(metafunc):
|
||||||
@pytest.mark.parametrize("version_id", [None, "second"])
|
@pytest.mark.parametrize("version_id", [None, "second"])
|
||||||
class TestS3GateLocking(TestS3GateBase):
|
class TestS3GateLocking(TestS3GateBase):
|
||||||
@allure.title("Test S3: Checking the operation of retention period & legal lock on the object")
|
@allure.title("Test S3: Checking the operation of retention period & legal lock on the object")
|
||||||
def test_s3_object_locking(self, version_id):
|
def test_s3_object_locking(self, version_id, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
retention_period = 2
|
retention_period = 2
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class TestS3GateLocking(TestS3GateBase):
|
||||||
|
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
s3_gate_object.put_object_s3(self.s3_client, bucket, file_path)
|
s3_gate_object.put_object_s3(self.s3_client, bucket, file_path)
|
||||||
file_name_1 = generate_file_with_content(file_path=file_path)
|
file_name_1 = generate_file_with_content(simple_object_size, file_path=file_path)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
check_objects_in_bucket(self.s3_client, bucket, [file_name])
|
check_objects_in_bucket(self.s3_client, bucket, [file_name])
|
||||||
if version_id:
|
if version_id:
|
||||||
|
@ -74,8 +74,8 @@ class TestS3GateLocking(TestS3GateBase):
|
||||||
s3_gate_object.delete_object_s3(self.s3_client, bucket, file_name, version_id)
|
s3_gate_object.delete_object_s3(self.s3_client, bucket, file_name, version_id)
|
||||||
|
|
||||||
@allure.title("Test S3: Checking the impossibility to change the retention mode COMPLIANCE")
|
@allure.title("Test S3: Checking the impossibility to change the retention mode COMPLIANCE")
|
||||||
def test_s3_mode_compliance(self, version_id):
|
def test_s3_mode_compliance(self, version_id, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
retention_period = 2
|
retention_period = 2
|
||||||
retention_period_1 = 1
|
retention_period_1 = 1
|
||||||
|
@ -115,8 +115,8 @@ class TestS3GateLocking(TestS3GateBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test S3: Checking the ability to change retention mode GOVERNANCE")
|
@allure.title("Test S3: Checking the ability to change retention mode GOVERNANCE")
|
||||||
def test_s3_mode_governance(self, version_id):
|
def test_s3_mode_governance(self, version_id, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
retention_period = 3
|
retention_period = 3
|
||||||
retention_period_1 = 2
|
retention_period_1 = 2
|
||||||
|
@ -183,8 +183,8 @@ class TestS3GateLocking(TestS3GateBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test S3: Checking if an Object Cannot Be Locked")
|
@allure.title("Test S3: Checking if an Object Cannot Be Locked")
|
||||||
def test_s3_legal_hold(self, version_id):
|
def test_s3_legal_hold(self, version_id, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
|
|
||||||
bucket = s3_gate_bucket.create_bucket_s3(self.s3_client, False)
|
bucket = s3_gate_bucket.create_bucket_s3(self.s3_client, False)
|
||||||
|
@ -205,8 +205,8 @@ class TestS3GateLocking(TestS3GateBase):
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
class TestS3GateLockingBucket(TestS3GateBase):
|
class TestS3GateLockingBucket(TestS3GateBase):
|
||||||
@allure.title("Test S3: Bucket Lock")
|
@allure.title("Test S3: Bucket Lock")
|
||||||
def test_s3_bucket_lock(self):
|
def test_s3_bucket_lock(self, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
configuration = {"Rule": {"DefaultRetention": {"Mode": "COMPLIANCE", "Days": 1}}}
|
configuration = {"Rule": {"DefaultRetention": {"Mode": "COMPLIANCE", "Days": 1}}}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ from random import choices, sample
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from aws_cli_client import AwsCliClient
|
from aws_cli_client import AwsCliClient
|
||||||
from common import ASSETS_DIR, COMPLEX_OBJ_SIZE, FREE_STORAGE, SIMPLE_OBJ_SIZE, WALLET_PASS
|
from common import ASSETS_DIR, FREE_STORAGE, 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 neofs_testlib.utils.wallet import init_wallet
|
||||||
|
@ -32,8 +32,8 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
return os.path.basename(full_path)
|
return os.path.basename(full_path)
|
||||||
|
|
||||||
@allure.title("Test S3: Copy object")
|
@allure.title("Test S3: Copy object")
|
||||||
def test_s3_copy_object(self, two_buckets):
|
def test_s3_copy_object(self, two_buckets, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
bucket_1_objects = [file_name]
|
bucket_1_objects = [file_name]
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
@allure.title("Test S3: Copy version of object")
|
@allure.title("Test S3: Copy version of object")
|
||||||
def test_s3_copy_version_object(self, two_buckets):
|
def test_s3_copy_version_object(self, two_buckets):
|
||||||
version_1_content = "Version 1"
|
version_1_content = "Version 1"
|
||||||
file_name_simple = generate_file_with_content(content=version_1_content)
|
file_name_simple = generate_file_with_content(simple_object_size, content=version_1_content)
|
||||||
obj_key = os.path.basename(file_name_simple)
|
obj_key = os.path.basename(file_name_simple)
|
||||||
|
|
||||||
bucket_1, bucket_2 = two_buckets
|
bucket_1, bucket_2 = two_buckets
|
||||||
|
@ -115,9 +115,9 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
s3_gate_object.copy_object_s3(self.s3_client, bucket_1, obj_key)
|
s3_gate_object.copy_object_s3(self.s3_client, bucket_1, obj_key)
|
||||||
|
|
||||||
@allure.title("Test S3: Checking copy with acl")
|
@allure.title("Test S3: Checking copy with acl")
|
||||||
def test_s3_copy_acl(self, bucket):
|
def test_s3_copy_acl(self, bucket, simple_object_size):
|
||||||
version_1_content = "Version 1"
|
version_1_content = "Version 1"
|
||||||
file_name_simple = generate_file_with_content(content=version_1_content)
|
file_name_simple = generate_file_with_content(simple_object_size, content=version_1_content)
|
||||||
obj_key = os.path.basename(file_name_simple)
|
obj_key = os.path.basename(file_name_simple)
|
||||||
|
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
@ -137,9 +137,9 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
), "Permission for all groups is FULL_CONTROL"
|
), "Permission for all groups is FULL_CONTROL"
|
||||||
|
|
||||||
@allure.title("Test S3: Copy object with metadata")
|
@allure.title("Test S3: Copy object with metadata")
|
||||||
def test_s3_copy_metadate(self, bucket):
|
def test_s3_copy_metadate(self, bucket, simple_object_size):
|
||||||
object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
bucket_1_objects = [file_name]
|
bucket_1_objects = [file_name]
|
||||||
|
|
||||||
|
@ -187,9 +187,9 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
), f"Metadata must be {object_metadata_1}"
|
), f"Metadata must be {object_metadata_1}"
|
||||||
|
|
||||||
@allure.title("Test S3: Copy object with tagging")
|
@allure.title("Test S3: Copy object with tagging")
|
||||||
def test_s3_copy_tagging(self, bucket):
|
def test_s3_copy_tagging(self, bucket, simple_object_size):
|
||||||
object_tagging = [(f"{uuid.uuid4()}", f"{uuid.uuid4()}")]
|
object_tagging = [(f"{uuid.uuid4()}", f"{uuid.uuid4()}")]
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name_simple = self.object_key_from_file_path(file_path)
|
file_name_simple = self.object_key_from_file_path(file_path)
|
||||||
bucket_1_objects = [file_name_simple]
|
bucket_1_objects = [file_name_simple]
|
||||||
|
|
||||||
|
@ -239,10 +239,10 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert tag in got_tags, f"Expected tag {tag} in {got_tags}"
|
assert tag in got_tags, f"Expected tag {tag} in {got_tags}"
|
||||||
|
|
||||||
@allure.title("Test S3: Delete version of object")
|
@allure.title("Test S3: Delete version of object")
|
||||||
def test_s3_delete_versioning(self, bucket):
|
def test_s3_delete_versioning(self, bucket, complex_object_size, simple_object_size):
|
||||||
version_1_content = "Version 1"
|
version_1_content = "Version 1"
|
||||||
version_2_content = "Version 2"
|
version_2_content = "Version 2"
|
||||||
file_name_simple = generate_file_with_content(content=version_1_content)
|
file_name_simple = generate_file_with_content(simple_object_size, content=version_1_content)
|
||||||
|
|
||||||
obj_key = os.path.basename(file_name_simple)
|
obj_key = os.path.basename(file_name_simple)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
@ -250,7 +250,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
||||||
file_name_1 = generate_file_with_content(
|
file_name_1 = generate_file_with_content(
|
||||||
file_path=file_name_simple, content=version_2_content
|
simple_object_size, file_path=file_name_simple, content=version_2_content
|
||||||
)
|
)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert not "DeleteMarkers" in delete_obj.keys(), "Delete markes not found"
|
assert not "DeleteMarkers" in delete_obj.keys(), "Delete markes not found"
|
||||||
|
|
||||||
with allure.step("Put new object into bucket"):
|
with allure.step("Put new object into bucket"):
|
||||||
file_name_simple = generate_file(COMPLEX_OBJ_SIZE)
|
file_name_simple = generate_file(complex_object_size)
|
||||||
obj_key = os.path.basename(file_name_simple)
|
obj_key = os.path.basename(file_name_simple)
|
||||||
version_id = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
version_id = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
||||||
|
|
||||||
|
@ -298,12 +298,12 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert "DeleteMarker" in delete_obj.keys(), f"Expected delete Marker"
|
assert "DeleteMarker" in delete_obj.keys(), f"Expected delete Marker"
|
||||||
|
|
||||||
@allure.title("Test S3: bulk delete version of object")
|
@allure.title("Test S3: bulk delete version of object")
|
||||||
def test_s3_bulk_delete_versioning(self, bucket):
|
def test_s3_bulk_delete_versioning(self, bucket, simple_object_size):
|
||||||
version_1_content = "Version 1"
|
version_1_content = "Version 1"
|
||||||
version_2_content = "Version 2"
|
version_2_content = "Version 2"
|
||||||
version_3_content = "Version 3"
|
version_3_content = "Version 3"
|
||||||
version_4_content = "Version 4"
|
version_4_content = "Version 4"
|
||||||
file_name_1 = generate_file_with_content(content=version_1_content)
|
file_name_1 = generate_file_with_content(simple_object_size, content=version_1_content)
|
||||||
|
|
||||||
obj_key = os.path.basename(file_name_1)
|
obj_key = os.path.basename(file_name_1)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
@ -311,15 +311,15 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
file_name_2 = generate_file_with_content(
|
file_name_2 = generate_file_with_content(
|
||||||
file_path=file_name_1, content=version_2_content
|
simple_object_size, file_path=file_name_1, content=version_2_content
|
||||||
)
|
)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_2)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_2)
|
||||||
file_name_3 = generate_file_with_content(
|
file_name_3 = generate_file_with_content(
|
||||||
file_path=file_name_1, content=version_3_content
|
simple_object_size, file_path=file_name_1, content=version_3_content
|
||||||
)
|
)
|
||||||
version_id_3 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_3)
|
version_id_3 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_3)
|
||||||
file_name_4 = generate_file_with_content(
|
file_name_4 = generate_file_with_content(
|
||||||
file_path=file_name_1, content=version_4_content
|
simple_object_size, file_path=file_name_1, content=version_4_content
|
||||||
)
|
)
|
||||||
version_id_4 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_4)
|
version_id_4 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_4)
|
||||||
version_ids = {version_id_1, version_id_2, version_id_3, version_id_4}
|
version_ids = {version_id_1, version_id_2, version_id_3, version_id_4}
|
||||||
|
@ -352,14 +352,14 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
def test_s3_get_versioning(self, bucket):
|
def test_s3_get_versioning(self, bucket):
|
||||||
version_1_content = "Version 1"
|
version_1_content = "Version 1"
|
||||||
version_2_content = "Version 2"
|
version_2_content = "Version 2"
|
||||||
file_name_simple = generate_file_with_content(content=version_1_content)
|
file_name_simple = generate_file_with_content(simple_object_size, content=version_1_content)
|
||||||
|
|
||||||
obj_key = os.path.basename(file_name_simple)
|
obj_key = os.path.basename(file_name_simple)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_simple)
|
||||||
file_name_1 = generate_file_with_content(
|
file_name_1 = generate_file_with_content(
|
||||||
file_path=file_name_simple, content=version_2_content
|
simple_object_size, file_path=file_name_simple, content=version_2_content
|
||||||
)
|
)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
|
|
||||||
|
@ -388,14 +388,14 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
), f"Get object with version {version_id_2}"
|
), f"Get object with version {version_id_2}"
|
||||||
|
|
||||||
@allure.title("Test S3: Get range")
|
@allure.title("Test S3: Get range")
|
||||||
def test_s3_get_range(self, bucket):
|
def test_s3_get_range(self, bucket, complex_object_size: int, simple_object_size: int):
|
||||||
file_path = generate_file(COMPLEX_OBJ_SIZE)
|
file_path = generate_file(complex_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
file_hash = get_file_hash(file_path)
|
file_hash = get_file_hash(file_path)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_path)
|
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_path)
|
||||||
file_name_1 = generate_file_with_content(file_path=file_path)
|
file_name_1 = generate_file_with_content(simple_object_size, file_path=file_path)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
|
|
||||||
with allure.step("Get first version of object"):
|
with allure.step("Get first version of object"):
|
||||||
|
@ -404,42 +404,46 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
version_id_1,
|
version_id_1,
|
||||||
range=[0, int(COMPLEX_OBJ_SIZE / 3)],
|
range=[0, int(complex_object_size / 3)],
|
||||||
)
|
)
|
||||||
object_1_part_2 = s3_gate_object.get_object_s3(
|
object_1_part_2 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
version_id_1,
|
version_id_1,
|
||||||
range=[int(COMPLEX_OBJ_SIZE / 3) + 1, 2 * int(COMPLEX_OBJ_SIZE / 3)],
|
range=[int(complex_object_size / 3) + 1, 2 * int(complex_object_size / 3)],
|
||||||
)
|
)
|
||||||
object_1_part_3 = s3_gate_object.get_object_s3(
|
object_1_part_3 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
version_id_1,
|
version_id_1,
|
||||||
range=[2 * int(COMPLEX_OBJ_SIZE / 3) + 1, COMPLEX_OBJ_SIZE],
|
range=[2 * int(complex_object_size / 3) + 1, complex_object_size],
|
||||||
)
|
)
|
||||||
con_file = concat_files([object_1_part_1, object_1_part_2, object_1_part_3])
|
con_file = concat_files([object_1_part_1, object_1_part_2, object_1_part_3])
|
||||||
assert get_file_hash(con_file) == file_hash, "Hashes must be the same"
|
assert get_file_hash(con_file) == file_hash, "Hashes must be the same"
|
||||||
|
|
||||||
with allure.step("Get second version of object"):
|
with allure.step("Get second version of object"):
|
||||||
object_2_part_1 = s3_gate_object.get_object_s3(
|
object_2_part_1 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client, bucket, file_name, version_id_2, range=[0, int(SIMPLE_OBJ_SIZE / 3)]
|
self.s3_client,
|
||||||
|
bucket,
|
||||||
|
file_name,
|
||||||
|
version_id_2,
|
||||||
|
range=[0, int(complex_object_size / 3)],
|
||||||
)
|
)
|
||||||
object_2_part_2 = s3_gate_object.get_object_s3(
|
object_2_part_2 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
version_id_2,
|
version_id_2,
|
||||||
range=[int(SIMPLE_OBJ_SIZE / 3) + 1, 2 * int(SIMPLE_OBJ_SIZE / 3)],
|
range=[int(simple_object_size / 3) + 1, 2 * int(simple_object_size / 3)],
|
||||||
)
|
)
|
||||||
object_2_part_3 = s3_gate_object.get_object_s3(
|
object_2_part_3 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
version_id_2,
|
version_id_2,
|
||||||
range=[2 * int(SIMPLE_OBJ_SIZE / 3) + 1, COMPLEX_OBJ_SIZE],
|
range=[2 * int(simple_object_size / 3) + 1, complex_object_size],
|
||||||
)
|
)
|
||||||
con_file_1 = concat_files([object_2_part_1, object_2_part_2, object_2_part_3])
|
con_file_1 = concat_files([object_2_part_1, object_2_part_2, object_2_part_3])
|
||||||
assert get_file_hash(con_file_1) == get_file_hash(
|
assert get_file_hash(con_file_1) == get_file_hash(
|
||||||
|
@ -448,28 +452,28 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
|
|
||||||
with allure.step("Get object"):
|
with allure.step("Get object"):
|
||||||
object_3_part_1 = s3_gate_object.get_object_s3(
|
object_3_part_1 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client, bucket, file_name, range=[0, int(SIMPLE_OBJ_SIZE / 3)]
|
self.s3_client, bucket, file_name, range=[0, int(simple_object_size / 3)]
|
||||||
)
|
)
|
||||||
object_3_part_2 = s3_gate_object.get_object_s3(
|
object_3_part_2 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
range=[int(SIMPLE_OBJ_SIZE / 3) + 1, 2 * int(SIMPLE_OBJ_SIZE / 3)],
|
range=[int(simple_object_size / 3) + 1, 2 * int(simple_object_size / 3)],
|
||||||
)
|
)
|
||||||
object_3_part_3 = s3_gate_object.get_object_s3(
|
object_3_part_3 = s3_gate_object.get_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
file_name,
|
file_name,
|
||||||
range=[2 * int(SIMPLE_OBJ_SIZE / 3) + 1, COMPLEX_OBJ_SIZE],
|
range=[2 * int(simple_object_size / 3) + 1, complex_object_size],
|
||||||
)
|
)
|
||||||
con_file = concat_files([object_3_part_1, object_3_part_2, object_3_part_3])
|
con_file = concat_files([object_3_part_1, object_3_part_2, object_3_part_3])
|
||||||
assert get_file_hash(con_file) == get_file_hash(file_name_1), "Hashes must be the same"
|
assert get_file_hash(con_file) == get_file_hash(file_name_1), "Hashes must be the same"
|
||||||
|
|
||||||
@allure.title("Test S3: Copy object with metadata")
|
@allure.title("Test S3: Copy object with metadata")
|
||||||
@pytest.mark.smoke
|
@pytest.mark.smoke
|
||||||
def test_s3_head_object(self, bucket):
|
def test_s3_head_object(self, bucket, complex_object_size, simple_object_size):
|
||||||
object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
||||||
file_path = generate_file(COMPLEX_OBJ_SIZE)
|
file_path = generate_file(complex_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
|
||||||
|
@ -477,7 +481,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(
|
version_id_1 = s3_gate_object.put_object_s3(
|
||||||
self.s3_client, bucket, file_path, Metadata=object_metadata
|
self.s3_client, bucket, file_path, Metadata=object_metadata
|
||||||
)
|
)
|
||||||
file_name_1 = generate_file_with_content(file_path=file_path)
|
file_name_1 = generate_file_with_content(simple_object_size, file_path=file_path)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
|
|
||||||
with allure.step("Get head of first version of object"):
|
with allure.step("Get head of first version of object"):
|
||||||
|
@ -506,10 +510,10 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
|
|
||||||
@allure.title("Test S3: list of object with versions")
|
@allure.title("Test S3: list of object with versions")
|
||||||
@pytest.mark.parametrize("list_type", ["v1", "v2"])
|
@pytest.mark.parametrize("list_type", ["v1", "v2"])
|
||||||
def test_s3_list_object(self, list_type: str, bucket):
|
def test_s3_list_object(self, list_type: str, bucket, complex_object_size):
|
||||||
file_path_1 = generate_file(COMPLEX_OBJ_SIZE)
|
file_path_1 = generate_file(complex_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path_1)
|
file_name = self.object_key_from_file_path(file_path_1)
|
||||||
file_path_2 = generate_file(COMPLEX_OBJ_SIZE)
|
file_path_2 = generate_file(complex_object_size)
|
||||||
file_name_2 = self.object_key_from_file_path(file_path_2)
|
file_name_2 = self.object_key_from_file_path(file_path_2)
|
||||||
|
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
@ -543,8 +547,8 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert "DeleteMarker" in delete_obj.keys(), f"Expected delete Marker"
|
assert "DeleteMarker" in delete_obj.keys(), f"Expected delete Marker"
|
||||||
|
|
||||||
@allure.title("Test S3: put object")
|
@allure.title("Test S3: put object")
|
||||||
def test_s3_put_object(self, bucket):
|
def test_s3_put_object(self, bucket, complex_object_size, simple_object_size):
|
||||||
file_path_1 = generate_file(COMPLEX_OBJ_SIZE)
|
file_path_1 = generate_file(complex_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path_1)
|
file_name = self.object_key_from_file_path(file_path_1)
|
||||||
object_1_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
object_1_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
||||||
tag_key_1 = "tag1"
|
tag_key_1 = "tag1"
|
||||||
|
@ -569,7 +573,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
], "Tags must be the same"
|
], "Tags must be the same"
|
||||||
|
|
||||||
with allure.step("Rewrite file into bucket"):
|
with allure.step("Rewrite file into bucket"):
|
||||||
file_path_2 = generate_file_with_content(file_path=file_path_1)
|
file_path_2 = generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client, bucket, file_path_2, Metadata=object_2_metadata, Tagging=tag_2
|
self.s3_client, bucket, file_path_2, Metadata=object_2_metadata, Tagging=tag_2
|
||||||
)
|
)
|
||||||
|
@ -583,7 +587,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
|
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
|
||||||
file_path_3 = generate_file(COMPLEX_OBJ_SIZE)
|
file_path_3 = generate_file(complex_object_size)
|
||||||
file_hash = get_file_hash(file_path_3)
|
file_hash = get_file_hash(file_path_3)
|
||||||
file_name_3 = self.object_key_from_file_path(file_path_3)
|
file_name_3 = self.object_key_from_file_path(file_path_3)
|
||||||
object_3_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
object_3_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
||||||
|
@ -604,7 +608,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
], "Tags must be the same"
|
], "Tags must be the same"
|
||||||
|
|
||||||
with allure.step("Put new version of file into bucket"):
|
with allure.step("Put new version of file into bucket"):
|
||||||
file_path_4 = generate_file_with_content(file_path=file_path_3)
|
file_path_4 = generate_file_with_content(simple_object_size, file_path=file_path_3)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_path_4)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_path_4)
|
||||||
versions = s3_gate_object.list_objects_versions_s3(self.s3_client, bucket)
|
versions = s3_gate_object.list_objects_versions_s3(self.s3_client, bucket)
|
||||||
obj_versions = {
|
obj_versions = {
|
||||||
|
@ -680,8 +684,15 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
|
|
||||||
@allure.title("Test S3: put object with ACL")
|
@allure.title("Test S3: put object with ACL")
|
||||||
@pytest.mark.parametrize("bucket_versioning", ["ENABLED", "SUSPENDED"])
|
@pytest.mark.parametrize("bucket_versioning", ["ENABLED", "SUSPENDED"])
|
||||||
def test_s3_put_object_acl(self, prepare_two_wallets, bucket_versioning, bucket):
|
def test_s3_put_object_acl(
|
||||||
file_path_1 = generate_file(COMPLEX_OBJ_SIZE)
|
self,
|
||||||
|
prepare_two_wallets,
|
||||||
|
bucket_versioning,
|
||||||
|
bucket,
|
||||||
|
complex_object_size,
|
||||||
|
simple_object_size,
|
||||||
|
):
|
||||||
|
file_path_1 = generate_file(complex_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path_1)
|
file_name = self.object_key_from_file_path(file_path_1)
|
||||||
if bucket_versioning == "ENABLED":
|
if bucket_versioning == "ENABLED":
|
||||||
status = s3_gate_bucket.VersioningStatus.ENABLED
|
status = s3_gate_bucket.VersioningStatus.ENABLED
|
||||||
|
@ -698,7 +709,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert get_file_hash(file_path_1) == get_file_hash(object_1), "Hashes must be the same"
|
assert get_file_hash(file_path_1) == get_file_hash(object_1), "Hashes must be the same"
|
||||||
|
|
||||||
with allure.step("Put object with acl public-read"):
|
with allure.step("Put object with acl public-read"):
|
||||||
file_path_2 = generate_file_with_content(file_path=file_path_1)
|
file_path_2 = generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
s3_gate_object.put_object_s3(self.s3_client, bucket, file_path_2, ACL="public-read")
|
s3_gate_object.put_object_s3(self.s3_client, bucket, file_path_2, ACL="public-read")
|
||||||
obj_acl = s3_gate_object.get_object_acl_s3(self.s3_client, bucket, file_name)
|
obj_acl = s3_gate_object.get_object_acl_s3(self.s3_client, bucket, file_name)
|
||||||
obj_permission = [permission.get("Permission") for permission in obj_acl]
|
obj_permission = [permission.get("Permission") for permission in obj_acl]
|
||||||
|
@ -710,7 +721,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert get_file_hash(file_path_2) == get_file_hash(object_2), "Hashes must be the same"
|
assert get_file_hash(file_path_2) == get_file_hash(object_2), "Hashes must be the same"
|
||||||
|
|
||||||
with allure.step("Put object with acl public-read-write"):
|
with allure.step("Put object with acl public-read-write"):
|
||||||
file_path_3 = generate_file_with_content(file_path=file_path_1)
|
file_path_3 = generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client, bucket, file_path_3, ACL="public-read-write"
|
self.s3_client, bucket, file_path_3, ACL="public-read-write"
|
||||||
)
|
)
|
||||||
|
@ -724,7 +735,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert get_file_hash(file_path_3) == get_file_hash(object_3), "Hashes must be the same"
|
assert get_file_hash(file_path_3) == get_file_hash(object_3), "Hashes must be the same"
|
||||||
|
|
||||||
with allure.step("Put object with acl authenticated-read"):
|
with allure.step("Put object with acl authenticated-read"):
|
||||||
file_path_4 = generate_file_with_content(file_path=file_path_1)
|
file_path_4 = generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client, bucket, file_path_4, ACL="authenticated-read"
|
self.s3_client, bucket, file_path_4, ACL="authenticated-read"
|
||||||
)
|
)
|
||||||
|
@ -737,11 +748,11 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
object_4 = s3_gate_object.get_object_s3(self.s3_client, bucket, file_name)
|
object_4 = s3_gate_object.get_object_s3(self.s3_client, bucket, file_name)
|
||||||
assert get_file_hash(file_path_4) == get_file_hash(object_4), "Hashes must be the same"
|
assert get_file_hash(file_path_4) == get_file_hash(object_4), "Hashes must be the same"
|
||||||
|
|
||||||
file_path_5 = generate_file(COMPLEX_OBJ_SIZE)
|
file_path_5 = generate_file(complex_object_size)
|
||||||
file_name_5 = self.object_key_from_file_path(file_path_5)
|
file_name_5 = self.object_key_from_file_path(file_path_5)
|
||||||
|
|
||||||
with allure.step("Put object with --grant-full-control id=mycanonicaluserid"):
|
with allure.step("Put object with --grant-full-control id=mycanonicaluserid"):
|
||||||
file_path_6 = generate_file_with_content(file_path=file_path_5)
|
file_path_6 = generate_file_with_content(simple_object_size, file_path=file_path_5)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -760,7 +771,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
with allure.step(
|
with allure.step(
|
||||||
"Put object with --grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers"
|
"Put object with --grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers"
|
||||||
):
|
):
|
||||||
file_path_7 = generate_file_with_content(file_path=file_path_5)
|
file_path_7 = generate_file_with_content(simple_object_size, file_path=file_path_5)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -777,9 +788,9 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
assert get_file_hash(file_path_7) == get_file_hash(object_7), "Hashes must be the same"
|
assert get_file_hash(file_path_7) == get_file_hash(object_7), "Hashes must be the same"
|
||||||
|
|
||||||
@allure.title("Test S3: put object with lock-mode")
|
@allure.title("Test S3: put object with lock-mode")
|
||||||
def test_s3_put_object_lock_mode(self, bucket):
|
def test_s3_put_object_lock_mode(self, bucket, complex_object_size, simple_object_size):
|
||||||
|
|
||||||
file_path_1 = generate_file(COMPLEX_OBJ_SIZE)
|
file_path_1 = generate_file(complex_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path_1)
|
file_name = self.object_key_from_file_path(file_path_1)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
|
|
||||||
|
@ -803,7 +814,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
"Put new version of object with [--object-lock-mode COMPLIANCE] и [--object-lock-retain-until-date +3days]"
|
"Put new version of object with [--object-lock-mode COMPLIANCE] и [--object-lock-retain-until-date +3days]"
|
||||||
):
|
):
|
||||||
date_obj = datetime.utcnow() + timedelta(days=2)
|
date_obj = datetime.utcnow() + timedelta(days=2)
|
||||||
file_name_1 = generate_file_with_content(file_path=file_path_1)
|
file_name_1 = generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -819,7 +830,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
"Put new version of object with [--object-lock-mode COMPLIANCE] и [--object-lock-retain-until-date +2days]"
|
"Put new version of object with [--object-lock-mode COMPLIANCE] и [--object-lock-retain-until-date +2days]"
|
||||||
):
|
):
|
||||||
date_obj = datetime.utcnow() + timedelta(days=3)
|
date_obj = datetime.utcnow() + timedelta(days=3)
|
||||||
file_name_1 = generate_file_with_content(file_path=file_path_1)
|
file_name_1 = generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
s3_gate_object.put_object_s3(
|
s3_gate_object.put_object_s3(
|
||||||
self.s3_client,
|
self.s3_client,
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -857,7 +868,7 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
|
|
||||||
@allure.title("Test S3 Sync directory")
|
@allure.title("Test S3 Sync directory")
|
||||||
@pytest.mark.parametrize("sync_type", ["sync", "cp"])
|
@pytest.mark.parametrize("sync_type", ["sync", "cp"])
|
||||||
def test_s3_sync_dir(self, sync_type, bucket):
|
def test_s3_sync_dir(self, sync_type, bucket, simple_object_size):
|
||||||
file_path_1 = os.path.join(os.getcwd(), ASSETS_DIR, "test_sync", "test_file_1")
|
file_path_1 = os.path.join(os.getcwd(), ASSETS_DIR, "test_sync", "test_file_1")
|
||||||
file_path_2 = os.path.join(os.getcwd(), ASSETS_DIR, "test_sync", "test_file_2")
|
file_path_2 = os.path.join(os.getcwd(), ASSETS_DIR, "test_sync", "test_file_2")
|
||||||
object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"}
|
||||||
|
@ -866,8 +877,8 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
if not isinstance(self.s3_client, AwsCliClient):
|
if not isinstance(self.s3_client, AwsCliClient):
|
||||||
pytest.skip("This test is not supported with boto3 client")
|
pytest.skip("This test is not supported with boto3 client")
|
||||||
|
|
||||||
generate_file_with_content(file_path=file_path_1)
|
generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
generate_file_with_content(file_path=file_path_2)
|
generate_file_with_content(simple_object_size, file_path=file_path_2)
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.ENABLED)
|
||||||
# TODO: return ACL, when https://github.com/nspcc-dev/neofs-s3-gw/issues/685 will be closed
|
# TODO: return ACL, when https://github.com/nspcc-dev/neofs-s3-gw/issues/685 will be closed
|
||||||
if sync_type == "sync":
|
if sync_type == "sync":
|
||||||
|
@ -909,10 +920,10 @@ class TestS3GateObject(TestS3GateBase):
|
||||||
# ], "Permission for all groups is FULL_CONTROL"
|
# ], "Permission for all groups is FULL_CONTROL"
|
||||||
|
|
||||||
@allure.title("Test S3 Put 10 nested level object")
|
@allure.title("Test S3 Put 10 nested level object")
|
||||||
def test_s3_put_10_folder(self, bucket, temp_directory):
|
def test_s3_put_10_folder(self, bucket, temp_directory, simple_object_size):
|
||||||
path = "/".join(["".join(choices(string.ascii_letters, k=3)) for _ in range(10)])
|
path = "/".join(["".join(choices(string.ascii_letters, k=3)) for _ in range(10)])
|
||||||
file_path_1 = os.path.join(temp_directory, path, "test_file_1")
|
file_path_1 = os.path.join(temp_directory, path, "test_file_1")
|
||||||
generate_file_with_content(file_path=file_path_1)
|
generate_file_with_content(simple_object_size, file_path=file_path_1)
|
||||||
file_name = self.object_key_from_file_path(file_path_1)
|
file_name = self.object_key_from_file_path(file_path_1)
|
||||||
objects_list = s3_gate_object.list_objects_s3(self.s3_client, bucket)
|
objects_list = s3_gate_object.list_objects_s3(self.s3_client, bucket)
|
||||||
assert not objects_list, f"Expected empty bucket, got {objects_list}"
|
assert not objects_list, f"Expected empty bucket, got {objects_list}"
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from random import choice
|
|
||||||
from string import ascii_letters
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from file_helper import generate_file, generate_file_with_content
|
from file_helper import generate_file
|
||||||
from python_keywords.container import search_container_by_name
|
from python_keywords.container import search_container_by_name
|
||||||
from python_keywords.storage_policy import get_simple_object_copies
|
from python_keywords.storage_policy import get_simple_object_copies
|
||||||
from s3_helper import (
|
from s3_helper import check_objects_in_bucket, object_key_from_file_path, set_bucket_versioning
|
||||||
assert_object_lock_mode,
|
|
||||||
check_objects_in_bucket,
|
|
||||||
object_key_from_file_path,
|
|
||||||
set_bucket_versioning,
|
|
||||||
)
|
|
||||||
|
|
||||||
from steps import s3_gate_bucket, s3_gate_object
|
from steps import s3_gate_bucket, s3_gate_object
|
||||||
from steps.s3_gate_base import TestS3GateBase
|
from steps.s3_gate_base import TestS3GateBase
|
||||||
|
@ -35,10 +25,10 @@ def pytest_generate_tests(metafunc):
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
class TestS3GatePolicy(TestS3GateBase):
|
class TestS3GatePolicy(TestS3GateBase):
|
||||||
@allure.title("Test S3: Verify bucket creation with retention policy applied")
|
@allure.title("Test S3: Verify bucket creation with retention policy applied")
|
||||||
def test_s3_bucket_location(self):
|
def test_s3_bucket_location(self, simple_object_size):
|
||||||
file_path_1 = generate_file()
|
file_path_1 = generate_file(simple_object_size)
|
||||||
file_name_1 = object_key_from_file_path(file_path_1)
|
file_name_1 = object_key_from_file_path(file_path_1)
|
||||||
file_path_2 = generate_file()
|
file_path_2 = generate_file(simple_object_size)
|
||||||
file_name_2 = object_key_from_file_path(file_path_2)
|
file_name_2 = object_key_from_file_path(file_path_2)
|
||||||
|
|
||||||
with allure.step("Create two buckets with different bucket configuration"):
|
with allure.step("Create two buckets with different bucket configuration"):
|
||||||
|
|
|
@ -32,8 +32,8 @@ class TestS3GateTagging(TestS3GateBase):
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
@allure.title("Test S3: Object tagging")
|
@allure.title("Test S3: Object tagging")
|
||||||
def test_s3_object_tagging(self, bucket):
|
def test_s3_object_tagging(self, bucket, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = object_key_from_file_path(file_path)
|
file_name = object_key_from_file_path(file_path)
|
||||||
|
|
||||||
with allure.step("Put with 3 tags object into bucket"):
|
with allure.step("Put with 3 tags object into bucket"):
|
||||||
|
|
|
@ -30,8 +30,8 @@ class TestS3GateVersioning(TestS3GateBase):
|
||||||
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.SUSPENDED)
|
set_bucket_versioning(self.s3_client, bucket, s3_gate_bucket.VersioningStatus.SUSPENDED)
|
||||||
|
|
||||||
@allure.title("Test S3: Enable and disable versioning")
|
@allure.title("Test S3: Enable and disable versioning")
|
||||||
def test_s3_version(self):
|
def test_s3_version(self, simple_object_size):
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
file_name = self.object_key_from_file_path(file_path)
|
file_name = self.object_key_from_file_path(file_path)
|
||||||
bucket_objects = [file_name]
|
bucket_objects = [file_name]
|
||||||
bucket = s3_gate_bucket.create_bucket_s3(self.s3_client, False)
|
bucket = s3_gate_bucket.create_bucket_s3(self.s3_client, False)
|
||||||
|
@ -61,7 +61,7 @@ class TestS3GateVersioning(TestS3GateBase):
|
||||||
|
|
||||||
with allure.step("Put several versions of object into bucket"):
|
with allure.step("Put several versions of object into bucket"):
|
||||||
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_path)
|
version_id_1 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_path)
|
||||||
file_name_1 = generate_file_with_content(file_path=file_path)
|
file_name_1 = generate_file_with_content(simple_object_size, file_path=file_path)
|
||||||
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
version_id_2 = s3_gate_object.put_object_s3(self.s3_client, bucket, file_name_1)
|
||||||
|
|
||||||
with allure.step("Check bucket shows all versions"):
|
with allure.step("Check bucket shows all versions"):
|
||||||
|
|
|
@ -5,10 +5,9 @@ from time import sleep
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from common import COMPLEX_OBJ_SIZE
|
|
||||||
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 python_keywords.container import create_container
|
||||||
from python_keywords.http_gate import (
|
from python_keywords.http_gate import (
|
||||||
get_via_http_curl,
|
get_via_http_curl,
|
||||||
get_via_http_gate,
|
get_via_http_gate,
|
||||||
|
@ -50,7 +49,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
TestHttpGate.wallet = default_wallet
|
TestHttpGate.wallet = default_wallet
|
||||||
|
|
||||||
@allure.title("Test Put over gRPC, Get over HTTP")
|
@allure.title("Test Put over gRPC, Get over HTTP")
|
||||||
def test_put_grpc_get_http(self):
|
def test_put_grpc_get_http(self, complex_object_size, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test that object can be put using gRPC interface and get using HTTP.
|
Test that object can be put using gRPC interface and get using HTTP.
|
||||||
|
|
||||||
|
@ -72,7 +71,9 @@ class TestHttpGate(ClusterTestBase):
|
||||||
rule=self.PLACEMENT_RULE_1,
|
rule=self.PLACEMENT_RULE_1,
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_large = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
|
|
||||||
with allure.step("Put objects using gRPC"):
|
with allure.step("Put objects using gRPC"):
|
||||||
oid_simple = put_object_to_random_node(
|
oid_simple = put_object_to_random_node(
|
||||||
|
@ -97,7 +98,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
@allure.link("https://github.com/nspcc-dev/neofs-http-gw#downloading", name="downloading")
|
@allure.link("https://github.com/nspcc-dev/neofs-http-gw#downloading", name="downloading")
|
||||||
@allure.title("Test Put over HTTP, Get over HTTP")
|
@allure.title("Test Put over HTTP, Get over HTTP")
|
||||||
@pytest.mark.smoke
|
@pytest.mark.smoke
|
||||||
def test_put_http_get_http(self):
|
def test_put_http_get_http(self, complex_object_size, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test that object can be put and get using HTTP interface.
|
Test that object can be put and get using HTTP interface.
|
||||||
|
|
||||||
|
@ -117,7 +118,9 @@ class TestHttpGate(ClusterTestBase):
|
||||||
rule=self.PLACEMENT_RULE_2,
|
rule=self.PLACEMENT_RULE_2,
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_large = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
|
|
||||||
with allure.step("Put objects using HTTP"):
|
with allure.step("Put objects using HTTP"):
|
||||||
oid_simple = upload_via_http_gate(
|
oid_simple = upload_via_http_gate(
|
||||||
|
@ -143,7 +146,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
],
|
],
|
||||||
ids=["simple", "hyphen", "percent"],
|
ids=["simple", "hyphen", "percent"],
|
||||||
)
|
)
|
||||||
def test_put_http_get_http_with_headers(self, attributes: dict):
|
def test_put_http_get_http_with_headers(self, attributes: dict, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test that object can be downloaded using different attributes in HTTP header.
|
Test that object can be downloaded using different attributes in HTTP header.
|
||||||
|
|
||||||
|
@ -163,7 +166,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
rule=self.PLACEMENT_RULE_2,
|
rule=self.PLACEMENT_RULE_2,
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
|
|
||||||
with allure.step("Put objects using HTTP with attribute"):
|
with allure.step("Put objects using HTTP with attribute"):
|
||||||
headers = self._attr_into_header(attributes)
|
headers = self._attr_into_header(attributes)
|
||||||
|
@ -179,7 +182,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
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):
|
def test_expiration_epoch_in_http(self, simple_object_size):
|
||||||
endpoint = self.cluster.default_rpc_endpoint
|
endpoint = self.cluster.default_rpc_endpoint
|
||||||
http_endpoint = self.cluster.default_http_gate_endpoint
|
http_endpoint = self.cluster.default_http_gate_endpoint
|
||||||
|
|
||||||
|
@ -190,7 +193,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
rule=self.PLACEMENT_RULE_2,
|
rule=self.PLACEMENT_RULE_2,
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
oids = []
|
oids = []
|
||||||
|
|
||||||
curr_epoch = get_epoch(self.shell, self.cluster)
|
curr_epoch = get_epoch(self.shell, self.cluster)
|
||||||
|
@ -228,7 +231,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
get_via_http_gate(cid=cid, oid=oid, endpoint=http_endpoint)
|
get_via_http_gate(cid=cid, oid=oid, endpoint=http_endpoint)
|
||||||
|
|
||||||
@allure.title("Test Zip in HTTP header")
|
@allure.title("Test Zip in HTTP header")
|
||||||
def test_zip_in_http(self):
|
def test_zip_in_http(self, complex_object_size, simple_object_size):
|
||||||
cid = create_container(
|
cid = create_container(
|
||||||
self.wallet,
|
self.wallet,
|
||||||
shell=self.shell,
|
shell=self.shell,
|
||||||
|
@ -236,7 +239,9 @@ class TestHttpGate(ClusterTestBase):
|
||||||
rule=self.PLACEMENT_RULE_2,
|
rule=self.PLACEMENT_RULE_2,
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_large = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
common_prefix = "my_files"
|
common_prefix = "my_files"
|
||||||
|
|
||||||
headers1 = {"X-Attribute-FilePath": f"{common_prefix}/file1"}
|
headers1 = {"X-Attribute-FilePath": f"{common_prefix}/file1"}
|
||||||
|
@ -267,7 +272,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
|
|
||||||
@pytest.mark.long
|
@pytest.mark.long
|
||||||
@allure.title("Test Put over HTTP/Curl, Get over HTTP/Curl for large object")
|
@allure.title("Test Put over HTTP/Curl, Get over HTTP/Curl for large object")
|
||||||
def test_put_http_get_http_large_file(self):
|
def test_put_http_get_http_large_file(self, complex_object_size):
|
||||||
"""
|
"""
|
||||||
This test checks upload and download using curl with 'large' object.
|
This test checks upload and download using curl with 'large' object.
|
||||||
Large is object with size up to 20Mb.
|
Large is object with size up to 20Mb.
|
||||||
|
@ -280,7 +285,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
|
|
||||||
obj_size = int(os.getenv("BIG_OBJ_SIZE", COMPLEX_OBJ_SIZE))
|
obj_size = int(os.getenv("BIG_OBJ_SIZE", complex_object_size))
|
||||||
file_path = generate_file(obj_size)
|
file_path = generate_file(obj_size)
|
||||||
|
|
||||||
with allure.step("Put objects using HTTP"):
|
with allure.step("Put objects using HTTP"):
|
||||||
|
@ -304,7 +309,7 @@ class TestHttpGate(ClusterTestBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
@allure.title("Test Put/Get over HTTP using Curl utility")
|
@allure.title("Test Put/Get over HTTP using Curl utility")
|
||||||
def test_put_http_get_http_curl(self):
|
def test_put_http_get_http_curl(self, complex_object_size, simple_object_size):
|
||||||
"""
|
"""
|
||||||
Test checks upload and download over HTTP using curl utility.
|
Test checks upload and download over HTTP using curl utility.
|
||||||
"""
|
"""
|
||||||
|
@ -315,7 +320,9 @@ class TestHttpGate(ClusterTestBase):
|
||||||
rule=self.PLACEMENT_RULE_2,
|
rule=self.PLACEMENT_RULE_2,
|
||||||
basic_acl=PUBLIC_ACL,
|
basic_acl=PUBLIC_ACL,
|
||||||
)
|
)
|
||||||
file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE)
|
file_path_simple, file_path_large = generate_file(simple_object_size), generate_file(
|
||||||
|
complex_object_size
|
||||||
|
)
|
||||||
|
|
||||||
with allure.step("Put objects using curl utility"):
|
with allure.step("Put objects using curl utility"):
|
||||||
oid_simple = upload_via_http_gate_curl(
|
oid_simple = upload_via_http_gate_curl(
|
||||||
|
|
|
@ -3,7 +3,7 @@ import random
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster_test_base import ClusterTestBase
|
from cluster_test_base import ClusterTestBase
|
||||||
from common import COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE, WALLET_PASS
|
from common import WALLET_PASS
|
||||||
from file_helper import generate_file
|
from file_helper import generate_file
|
||||||
from grpc_responses import SESSION_NOT_FOUND
|
from grpc_responses import SESSION_NOT_FOUND
|
||||||
from neofs_testlib.utils.wallet import get_last_address_from_wallet
|
from neofs_testlib.utils.wallet import get_last_address_from_wallet
|
||||||
|
@ -19,7 +19,7 @@ class TestDynamicObjectSession(ClusterTestBase):
|
||||||
@allure.title("Test Object Operations with Session Token")
|
@allure.title("Test Object Operations with Session Token")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
def test_object_session_token(self, default_wallet, object_size):
|
def test_object_session_token(self, default_wallet, object_size):
|
||||||
|
|
|
@ -4,7 +4,6 @@ import allure
|
||||||
import pytest
|
import pytest
|
||||||
from cluster import Cluster
|
from cluster import Cluster
|
||||||
from cluster_test_base import ClusterTestBase
|
from cluster_test_base import ClusterTestBase
|
||||||
from common import COMPLEX_OBJ_SIZE, SIMPLE_OBJ_SIZE
|
|
||||||
from epoch import ensure_fresh_epoch
|
from epoch import ensure_fresh_epoch
|
||||||
from file_helper import generate_file
|
from file_helper import generate_file
|
||||||
from grpc_responses import MALFORMED_REQUEST, OBJECT_ACCESS_DENIED, OBJECT_NOT_FOUND
|
from grpc_responses import MALFORMED_REQUEST, OBJECT_ACCESS_DENIED, OBJECT_NOT_FOUND
|
||||||
|
@ -13,7 +12,6 @@ from pytest import FixtureRequest
|
||||||
from python_keywords.container import create_container
|
from python_keywords.container import create_container
|
||||||
from python_keywords.neofs_verbs import (
|
from python_keywords.neofs_verbs import (
|
||||||
delete_object,
|
delete_object,
|
||||||
get_netmap_netinfo,
|
|
||||||
get_object,
|
get_object,
|
||||||
get_object_from_random_node,
|
get_object_from_random_node,
|
||||||
get_range,
|
get_range,
|
||||||
|
@ -58,7 +56,7 @@ def storage_containers(
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
params=[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
params=[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
# Scope module to upload/delete each files set only once
|
# Scope module to upload/delete each files set only once
|
||||||
scope="module",
|
scope="module",
|
||||||
|
@ -98,16 +96,15 @@ def storage_objects(
|
||||||
|
|
||||||
|
|
||||||
@allure.step("Get ranges for test")
|
@allure.step("Get ranges for test")
|
||||||
def get_ranges(storage_object: StorageObjectInfo, shell: Shell, endpoint: str) -> list[str]:
|
def get_ranges(
|
||||||
|
storage_object: StorageObjectInfo, max_object_size: int, shell: Shell, endpoint: str
|
||||||
|
) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Returns ranges to test range/hash methods via static session
|
Returns ranges to test range/hash methods via static session
|
||||||
"""
|
"""
|
||||||
object_size = storage_object.size
|
object_size = storage_object.size
|
||||||
|
|
||||||
if object_size == COMPLEX_OBJ_SIZE:
|
if object_size > max_object_size:
|
||||||
net_info = get_netmap_netinfo(storage_object.wallet_file_path, shell, endpoint)
|
|
||||||
max_object_size = net_info["maximum_object_size"]
|
|
||||||
# make sure to test multiple parts of complex object
|
|
||||||
assert object_size >= max_object_size + RANGE_OFFSET_FOR_COMPLEX_OBJECT
|
assert object_size >= max_object_size + RANGE_OFFSET_FOR_COMPLEX_OBJECT
|
||||||
return [
|
return [
|
||||||
"0:10",
|
"0:10",
|
||||||
|
@ -160,9 +157,9 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
method_under_test,
|
method_under_test,
|
||||||
verb: str,
|
verb: ObjectVerb,
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -175,9 +172,9 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
for node in self.cluster.storage_nodes:
|
for node in self.cluster.storage_nodes:
|
||||||
for storage_object in storage_objects[0:2]:
|
for storage_object in storage_objects[0:2]:
|
||||||
method_under_test(
|
method_under_test(
|
||||||
user_wallet.path,
|
wallet=user_wallet.path,
|
||||||
storage_object.cid,
|
cid=storage_object.cid,
|
||||||
storage_object.oid,
|
oid=storage_object.oid,
|
||||||
shell=self.shell,
|
shell=self.shell,
|
||||||
endpoint=node.get_rpc_endpoint(),
|
endpoint=node.get_rpc_endpoint(),
|
||||||
session=static_sessions[verb],
|
session=static_sessions[verb],
|
||||||
|
@ -193,10 +190,11 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
method_under_test,
|
method_under_test,
|
||||||
verb: str,
|
verb: ObjectVerb,
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
|
max_object_size,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Validate static session with range operations
|
Validate static session with range operations
|
||||||
|
@ -205,7 +203,9 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
f"Validate static session with range operations for {request.node.callspec.id}"
|
f"Validate static session with range operations for {request.node.callspec.id}"
|
||||||
)
|
)
|
||||||
storage_object = storage_objects[0]
|
storage_object = storage_objects[0]
|
||||||
ranges_to_test = get_ranges(storage_object, self.shell, self.cluster.default_rpc_endpoint)
|
ranges_to_test = get_ranges(
|
||||||
|
storage_object, max_object_size, self.shell, self.cluster.default_rpc_endpoint
|
||||||
|
)
|
||||||
|
|
||||||
for range_to_test in ranges_to_test:
|
for range_to_test in ranges_to_test:
|
||||||
with allure.step(f"Check range {range_to_test}"):
|
with allure.step(f"Check range {range_to_test}"):
|
||||||
|
@ -227,7 +227,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -253,7 +253,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -278,7 +278,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
stranger_wallet: WalletFile,
|
stranger_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -305,7 +305,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -333,7 +333,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
storage_containers: list[str],
|
storage_containers: list[str],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -361,7 +361,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
owner_wallet: WalletFile,
|
owner_wallet: WalletFile,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
stranger_wallet: WalletFile,
|
stranger_wallet: WalletFile,
|
||||||
storage_containers: list[int],
|
storage_containers: list[str],
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
temp_directory: str,
|
temp_directory: str,
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
|
@ -638,7 +638,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -663,7 +663,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
||||||
self,
|
self,
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
storage_objects: list[StorageObjectInfo],
|
storage_objects: list[StorageObjectInfo],
|
||||||
static_sessions: list[str],
|
static_sessions: dict[ObjectVerb, str],
|
||||||
request: FixtureRequest,
|
request: FixtureRequest,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -148,6 +148,7 @@ class TestSessionTokenContainer(ClusterTestBase):
|
||||||
user_wallet: WalletFile,
|
user_wallet: WalletFile,
|
||||||
stranger_wallet: WalletFile,
|
stranger_wallet: WalletFile,
|
||||||
static_sessions: dict[ContainerVerb, str],
|
static_sessions: dict[ContainerVerb, str],
|
||||||
|
simple_object_size,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Validate static session with set eacl operation
|
Validate static session with set eacl operation
|
||||||
|
@ -159,7 +160,7 @@ class TestSessionTokenContainer(ClusterTestBase):
|
||||||
shell=self.shell,
|
shell=self.shell,
|
||||||
endpoint=self.cluster.default_rpc_endpoint,
|
endpoint=self.cluster.default_rpc_endpoint,
|
||||||
)
|
)
|
||||||
file_path = generate_file()
|
file_path = generate_file(simple_object_size)
|
||||||
assert can_put_object(stranger_wallet.path, cid, file_path, self.shell, self.cluster)
|
assert can_put_object(stranger_wallet.path, cid, file_path, self.shell, self.cluster)
|
||||||
|
|
||||||
with allure.step(f"Deny all operations for other via eACL"):
|
with allure.step(f"Deny all operations for other via eACL"):
|
||||||
|
|
|
@ -55,6 +55,7 @@ pyflakes==2.4.0
|
||||||
pyparsing==3.0.9
|
pyparsing==3.0.9
|
||||||
pyrsistent==0.18.1
|
pyrsistent==0.18.1
|
||||||
pytest==7.1.2
|
pytest==7.1.2
|
||||||
|
pytest-lazy-fixture==0.6.3
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
pyyaml==6.0
|
pyyaml==6.0
|
||||||
requests==2.28.0
|
requests==2.28.0
|
||||||
|
|
|
@ -7,7 +7,7 @@ from typing import Optional
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
from cluster import Cluster
|
from cluster import Cluster
|
||||||
from common import COMPLEX_OBJ_SIZE, NEOFS_CLI_EXEC, SIMPLE_OBJ_SIZE, WALLET_CONFIG
|
from common import NEOFS_CLI_EXEC, WALLET_CONFIG
|
||||||
from complex_object_actions import get_link_object
|
from complex_object_actions import get_link_object
|
||||||
from neofs_testlib.cli import NeofsCli
|
from neofs_testlib.cli import NeofsCli
|
||||||
from neofs_testlib.shell import Shell
|
from neofs_testlib.shell import Shell
|
||||||
|
@ -201,12 +201,13 @@ def verify_get_storage_group(
|
||||||
gid: str,
|
gid: str,
|
||||||
obj_list: list,
|
obj_list: list,
|
||||||
object_size: int,
|
object_size: int,
|
||||||
|
max_object_size: int,
|
||||||
bearer: str = None,
|
bearer: str = None,
|
||||||
wallet_config: str = WALLET_CONFIG,
|
wallet_config: str = WALLET_CONFIG,
|
||||||
):
|
):
|
||||||
obj_parts = []
|
obj_parts = []
|
||||||
endpoint = cluster.default_rpc_endpoint
|
endpoint = cluster.default_rpc_endpoint
|
||||||
if object_size == COMPLEX_OBJ_SIZE:
|
if object_size > max_object_size:
|
||||||
for obj in obj_list:
|
for obj in obj_list:
|
||||||
link_oid = get_link_object(
|
link_oid = get_link_object(
|
||||||
wallet,
|
wallet,
|
||||||
|
@ -239,11 +240,10 @@ def verify_get_storage_group(
|
||||||
bearer=bearer,
|
bearer=bearer,
|
||||||
wallet_config=wallet_config,
|
wallet_config=wallet_config,
|
||||||
)
|
)
|
||||||
if object_size == SIMPLE_OBJ_SIZE:
|
exp_size = object_size * obj_num
|
||||||
exp_size = SIMPLE_OBJ_SIZE * obj_num
|
if object_size < max_object_size:
|
||||||
assert int(storagegroup_data["Group size"]) == exp_size
|
assert int(storagegroup_data["Group size"]) == exp_size
|
||||||
assert storagegroup_data["Members"] == obj_list
|
assert storagegroup_data["Members"] == obj_list
|
||||||
else:
|
else:
|
||||||
exp_size = COMPLEX_OBJ_SIZE * obj_num
|
|
||||||
assert int(storagegroup_data["Group size"]) == exp_size
|
assert int(storagegroup_data["Group size"]) == exp_size
|
||||||
assert storagegroup_data["Members"] == obj_parts
|
assert storagegroup_data["Members"] == obj_parts
|
||||||
|
|
|
@ -4,9 +4,9 @@ import yaml
|
||||||
|
|
||||||
CONTAINER_WAIT_INTERVAL = "1m"
|
CONTAINER_WAIT_INTERVAL = "1m"
|
||||||
|
|
||||||
# TODO: Get object size data from a node config
|
SIMPLE_OBJECT_SIZE = os.getenv("SIMPLE_OBJECT_SIZE", "1000")
|
||||||
SIMPLE_OBJ_SIZE = int(os.getenv("SIMPLE_OBJ_SIZE", "1000"))
|
COMPLEX_OBJECT_CHUNKS_COUNT = os.getenv("COMPLEX_OBJECT_CHUNKS_COUNT", "3")
|
||||||
COMPLEX_OBJ_SIZE = int(os.getenv("COMPLEX_OBJ_SIZE", "2000"))
|
COMPLEX_OBJECT_TAIL_SIZE = os.getenv("COMPLEX_OBJECT_TAIL_SIZE", "1000")
|
||||||
|
|
||||||
MAINNET_BLOCK_TIME = os.getenv("MAINNET_BLOCK_TIME", "1s")
|
MAINNET_BLOCK_TIME = os.getenv("MAINNET_BLOCK_TIME", "1s")
|
||||||
MAINNET_TIMEOUT = os.getenv("MAINNET_TIMEOUT", "1min")
|
MAINNET_TIMEOUT = os.getenv("MAINNET_TIMEOUT", "1min")
|
||||||
|
|
Loading…
Reference in a new issue