Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: verify COMMON_PREFIX search filter, closes #244 #658

Merged
merged 1 commit into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 87 additions & 6 deletions pytest_tests/testsuites/object/test_object_api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import logging
import os
import random
import sys

import allure
import pytest
from cluster import Cluster
from common import ASSETS_DIR, TEST_FILES_DIR
from complex_object_actions import get_complex_object_split_ranges
from file_helper import generate_file, get_file_content, get_file_hash
from grpc_responses import (
Expand All @@ -16,7 +18,7 @@
)
from neofs_testlib.shell import Shell
from pytest import FixtureRequest
from python_keywords.container import create_container
from python_keywords.container import create_container, delete_container
from python_keywords.neofs_verbs import (
get_object_from_random_node,
get_range,
Expand Down Expand Up @@ -135,6 +137,14 @@ def storage_objects(
with expect_not_raises():
delete_objects(storage_objects, client_shell, cluster)

@pytest.fixture
def container(default_wallet: str, client_shell: Shell, cluster: Cluster) -> str:
cid = create_container(default_wallet, shell=client_shell, endpoint=cluster.default_rpc_endpoint)
yield cid
delete_container(
default_wallet, cid, shell=client_shell, endpoint=cluster.default_rpc_endpoint
)


@pytest.mark.grpc_api
class TestObjectApi(ClusterTestBase):
Expand Down Expand Up @@ -233,10 +243,22 @@ def test_search_object_api(
wallet = storage_objects[0].wallet_file_path
cid = storage_objects[0].cid

def _generate_filters_expressions(attrib_dict: dict[str, str]):
return [f"{filter_key} EQ {filter_val}" for filter_key, filter_val in attrib_dict.items()]

test_table = [
(OBJECT_ATTRIBUTES[1], oids[1:2]),
(OBJECT_ATTRIBUTES[2], oids[2:3]),
(COMMON_ATTRIBUTE, oids[1:3]),
(
_generate_filters_expressions(OBJECT_ATTRIBUTES[1]),
oids[1:2]
),
(
_generate_filters_expressions(OBJECT_ATTRIBUTES[2]),
oids[2:3]
),
(
_generate_filters_expressions(COMMON_ATTRIBUTE),
oids[1:3]
),
]

with allure.step("Search objects"):
Expand All @@ -252,13 +274,13 @@ def test_search_object_api(
assert sorted(oids) == sorted(result)

# search by test table
for filter, expected_oids in test_table:
for _filter, expected_oids in test_table:
result = search_object(
wallet,
cid,
shell=self.shell,
endpoint=self.cluster.default_rpc_endpoint,
filters=filter,
filters=_filter,
expected_objects_list=expected_oids,
root=True,
)
Expand Down Expand Up @@ -337,6 +359,65 @@ def test_object_search_should_return_tombstone_items(
object_type == "TOMBSTONE"
), f"Object wasn't deleted properly. Found object {tombstone_oid} with type {object_type}"

@allure.title("Validate objects search by common prefix")
def test_search_object_api_common_prefix(self, default_wallet: str, simple_object_size: int, container: str):
FILEPATH_ATTR_NAME = "FilePath"
vvarg229 marked this conversation as resolved.
Show resolved Hide resolved
NUMBER_OF_OBJECTS = 5
wallet = default_wallet

objects = {}
for _ in range(NUMBER_OF_OBJECTS):
file_path = generate_file(simple_object_size)

with allure.step("Put objects"):
objects[file_path] = put_object_to_random_node(
vvarg229 marked this conversation as resolved.
Show resolved Hide resolved
wallet=wallet,
path=file_path,
cid=container,
shell=self.shell,
cluster=self.cluster,
attributes={FILEPATH_ATTR_NAME: file_path}
)
all_oids = sorted(objects.values())

for common_prefix, expected_oids in (
('/', all_oids),
(os.path.join(os.getcwd(), ASSETS_DIR), all_oids),
(os.path.join(os.getcwd(), ASSETS_DIR, TEST_FILES_DIR), all_oids),
(file_path, [objects[file_path]])
):
with allure.step(f"Search objects by path: {common_prefix}"):
search_object(
wallet,
container,
shell=self.shell,
endpoint=self.cluster.default_rpc_endpoint,
filters=[f"{FILEPATH_ATTR_NAME} COMMON_PREFIX {common_prefix}"],
expected_objects_list=expected_oids,
root=True,
fail_on_assert=True
)

for common_prefix in (
vvarg229 marked this conversation as resolved.
Show resolved Hide resolved
f"{file_path}/o123"
'/COMMON_PREFIX',
'?',
'213'
):

with allure.step(f"Search objects by path: {common_prefix}"):
with pytest.raises(AssertionError):
search_object(
wallet,
container,
shell=self.shell,
endpoint=self.cluster.default_rpc_endpoint,
filters=[f"{FILEPATH_ATTR_NAME} COMMON_PREFIX {common_prefix}"],
expected_objects_list=expected_oids,
root=True,
fail_on_assert=True
)

@allure.title("Validate native object API get_range_hash")
@pytest.mark.grpc_api
def test_object_get_range_hash(
Expand Down
18 changes: 9 additions & 9 deletions robot/resources/lib/python_keywords/neofs_verbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,14 @@ def search_object(
shell: Shell,
endpoint: str,
bearer: str = "",
filters: Optional[dict] = None,
filters: Optional[list] = None,
expected_objects_list: Optional[list] = None,
wallet_config: Optional[str] = None,
xhdr: Optional[dict] = None,
session: Optional[str] = None,
phy: bool = False,
root: bool = False,
fail_on_assert = False
) -> list:
"""
SEARCH an Object.
Expand All @@ -454,13 +455,14 @@ def search_object(
shell: executor for cli command
bearer: path to Bearer Token file, appends to `--bearer` key
endpoint: NeoFS endpoint to send request to, appends to `--rpc-endpoint` key
filters: key=value pairs to filter Objects
filters: list of filter objects
expected_objects_list: a list of ObjectIDs to compare found Objects with
wallet_config: path to the wallet config
xhdr: Request X-Headers in form of Key=Value
session: path to a JSON-encoded container session token
phy: Search physically stored objects.
root: Search for user objects.
fail_on_assert: fail if expected_objects_list is not matched to the found objects list.

Returns:
list of found ObjectIDs
Expand All @@ -473,9 +475,7 @@ def search_object(
cid=cid,
bearer=bearer,
xhdr=xhdr,
filters=[f"{filter_key} EQ {filter_val}" for filter_key, filter_val in filters.items()]
if filters
else None,
filters=filters,
session=session,
phy=phy,
root=root,
Expand All @@ -490,10 +490,10 @@ def search_object(
f"is equal for expected list '{expected_objects_list}'"
)
else:
logger.warning(
f"Found object list {found_objects} "
f"is not equal to expected list '{expected_objects_list}'"
)
warning = f"Found object list {found_objects} is not equal to expected list '{expected_objects_list}'"
logger.warning(warning)
if fail_on_assert:
raise AssertionError(warning)

return found_objects

Expand Down
Loading