frostfs-testcases/pytest_tests/testsuites/container/test_policy.py
2023-09-25 13:59:17 +00:00

477 lines
No EOL
18 KiB
Python

from frostfs_testlib.steps.cli.container import (
create_container,
delete_container,
get_container,
)
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
from pytest_tests.helpers.utility import placement_policy_from_container
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
from frostfs_testlib.utils.file_utils import generate_file
import allure
import pytest
from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL
from frostfs_testlib.steps.cli.container import create_container, get_container
from frostfs_testlib.steps.cli.object import (
put_object_to_random_node,
)
from frostfs_testlib.steps.node_management import (
check_node_in_map,
)
from frostfs_testlib.steps.storage_policy import get_nodes_with_object, get_simple_object_copies
from pytest_tests.helpers.utility import (
placement_policy_from_container,
)
@pytest.mark.container
@pytest.mark.policy
class TestPolicy(ClusterTestBase):
@pytest.mark.skip(reason="ошибка с фикстурой")
@allure.title("[NEGATIVE] Placement policy")
@pytest.mark.policy
def test_placement_policy_negative(
self, default_wallet, placement_rule
):
"""
Negative test for placement policy.
"""
wallet = default_wallet
endpoint = self.cluster.default_rpc_endpoint
try:
cid = create_container(
wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint
)
except:
got_policy = placement_policy_from_container(
get_container(wallet, cid, json_mode=False, shell=self.shell, endpoint=endpoint)
)
assert got_policy == placement_rule.replace(
"'", ""
), f"Can't parse placement policy"
@pytest.mark.skip(reason="ошибка с фикстурой")
@allure.title("110569 [NEGATIVE] Placement policy: Not enough nodes to SELECT")
@pytest.mark.policy
def test_placement_policy_negative_not_enough_nodes_to_select(
self, default_wallet, placement_rule
):
"""
Negative test for placement policy: Not enough nodes to SELECT.
"""
wallet = default_wallet
endpoint = self.cluster.default_rpc_endpoint
with pytest.raises(RuntimeError, match=".*not enough nodes to SELECT from.*"):
cid = create_container(
wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint
)
@pytest.mark.skip(reason="ошибка с фикстурой")
@allure.title("110570 [NEGATIVE] Placement policy: Filter not found")
@pytest.mark.policy
def test_placement_policy_negative_not_enough_nodes_to_filter(
self, default_wallet, placement_rule
):
"""
Negative test for placement policy: Filter not found.
"""
wallet = default_wallet
endpoint = self.cluster.default_rpc_endpoint
with pytest.raises(RuntimeError, match=".*not enough nodes to FILTER from.*"):
cid = create_container(
wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint
)
@pytest.mark.skip(reason="ошибка с фикстурой")
@allure.title("110572 [NEGATIVE] Placement policy: SELECTOR not found")
@pytest.mark.policy
def test_placement_policy_negative_not_enough_nodes_to_selector(
self, default_wallet, placement_rule
):
"""
Negative test for placement policy: Filter not found.
"""
wallet = default_wallet
endpoint = self.cluster.default_rpc_endpoint
with pytest.raises(RuntimeError, match=".*not enough nodes to SELECTOR from.*"):
cid = create_container(
wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint
)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("REP 1 REP 1 CBF 1", 2, {2, 2}),
]
)
@pytest.mark.policy
@allure.title("110571 Object should have {expected_copies} copies with policy {placement_rule}")
def test_simple_policy_results_with_one_node(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement simple policy results with one node.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("UNIQUE REP 1 IN AnyNode REP 1 IN AnyNode CBF 1 SELECT 1 FROM * AS AnyNode", 2, {2, 3}),
]
)
@pytest.mark.policy
@allure.title("110544 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_results_with_unique_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with SELECT results with UNIQUE nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
('UNIQUE REP 1 IN RUS REP 1 IN RUS CBF 1 SELECT 1 FROM RU AS RUS FILTER Country NE Sweden AS NotSE FILTER @NotSE AND NOT (CountryCode EQ FI) AND Country EQ "Russia" AS RU', 2, {3, 1}),
]
)
@pytest.mark.policy
@allure.title("110545 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_and_complex_filter_results_with_unique_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with SELECT and Complex FILTER results with UNIQUE nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("""REP 4""",
4, {3, 2, 1, 4}),
]
)
@pytest.mark.policy
@allure.title("110610 Object should have {expected_copies} copies with policy {placement_rule}")
def test_simple_policy_results_with_100_of_available_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement simple policy results with 100% of available nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("UNIQUE REP 1 REP 1 CBF 1", 2, {2, 3}),
]
)
@pytest.mark.policy
@allure.title("110537 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_and_complex_filter_results_with_unique_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement simple policy results with UNIQUE nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("UNIQUE REP 1 REP 1 CBF 1", 2, {2, 3}),
]
)
@pytest.mark.policy
@allure.title("110587 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_multi_selects_and_filters_results_with_one_node(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with Multi SELECTs and FILTERs results with one nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("REP 1 CBF 1", 1, {2}),
]
)
@pytest.mark.policy
@allure.title("110593 Object should have {expected_copies} copies with policy {placement_rule}")
def test_simple_policy_results_with_25_of_available_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy results with 25% of available nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("REP 1 IN One CBF 1 SELECT 1 FROM * AS One", 1, {2}),
]
)
@pytest.mark.policy
@allure.title("110594 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_results_with_25_of_available_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with SELECT results with 25% of available nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("REP 1 IN Nodes25 SELECT 1 FROM LE10 AS Nodes25 FILTER Price LE 10 AS LE10", 1, {2}),
]
)
@pytest.mark.policy
@allure.title("110595 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_and_filter_results_with_25_of_available_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with SELECT and FILTER results with 25% of available nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("""REP 1 IN Nodes25 SELECT 1 FROM BET0AND10 AS Nodes25 FILTER Price LE 10 AS LE10 FILTER Price GT 0 AS GT0 FILTER @LE10 AND @GT0 AS BET0AND10""",
1, {1}),
]
)
@pytest.mark.policy
@allure.title("110596 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_and_complex_filter_results_with_25_of_available_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
complex_object_size: ObjectSize,
):
"""
110596 This test checks object's copies based on container's placement policy with SELECT and Complex FILTER results with 25% of available nodes.
"""
wallet = default_wallet
file_path = generate_file(complex_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("""UNIQUE REP 1 IN MyRussianNodes REP 1 IN MyRussianNodes CBF 1 SELECT 1 FROM RussianNodes AS MyRussianNodes FILTER Country EQ Russia AS RussianNodes""",
2, {3, 1}),
]
)
@pytest.mark.policy
@allure.title("110588 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_and_filter_results_with_unique_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with SELECT and FILTER results with UNIQUE nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@pytest.mark.parametrize(
"placement_rule,expected_copies,expected_nodes_id",
[
("""UNIQUE REP 1 IN MyRussianNodes REP 1 IN MyRussianNodes CBF 1 SELECT 1 FROM RussianNodes AS MyRussianNodes FILTER Country EQ Russia AS RussianNodes""",
2, {3, 1}),
]
)
@pytest.mark.policy
@allure.title("110586 Object should have {expected_copies} copies with policy {placement_rule}")
def test_policy_with_select_and_filter_results_with_unique_nodes(
self,
default_wallet,
placement_rule,
expected_copies,
expected_nodes_id: set[int],
simple_object_size: ObjectSize,
):
"""
This test checks object's copies based on container's placement policy with SELECT and FILTER results with UNIQUE nodes.
"""
wallet = default_wallet
file_path = generate_file(simple_object_size.value)
cid, oid = self.validate_object_copies(
wallet, placement_rule, file_path
)
self.check_expected_copies(cid, oid, expected_copies, expected_nodes_id)
@allure.step("Validate policy")
def validate_object_policy(
self, wallet: str, placement_rule: str, cid: str, endpoint: str
):
got_policy = placement_policy_from_container(
get_container(wallet, cid, json_mode=False, shell=self.shell, endpoint=endpoint)
)
assert got_policy == placement_rule.replace(
"'", ""
), f"Expected \n{placement_rule} and got policy \n{got_policy} are the same"
@allure.step("Validate expected copies")
def check_expected_copies(self, cid: str, oid: str, expected_copies: int, expected_copies_id: set):
nodes = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes)
assert len(nodes) == expected_copies, f"Expected {expected_copies} copies, got {len(nodes)}"
nodes_id = {node.id for node in nodes}
assert nodes_id == expected_copies_id, f"Expected {expected_copies_id} copies, got {nodes_id}"
@allure.step("Validate object copies")
def validate_object_copies(
self, wallet: str, placement_rule: str, file_path: str
) -> set[int]:
endpoint = self.cluster.default_rpc_endpoint
with allure.step(f"Create container"):
cid = create_container(
wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint
)
self.validate_object_policy(wallet, placement_rule, cid, endpoint)
with allure.step(f"Put object"):
oid = put_object_to_random_node(
wallet, file_path, cid, shell=self.shell, cluster=self.cluster
)
return cid, oid