diff --git a/pytest_tests/testsuites/services/test_http_gate.py b/pytest_tests/testsuites/services/test_http_gate.py index a1a81e9..440f7af 100644 --- a/pytest_tests/testsuites/services/test_http_gate.py +++ b/pytest_tests/testsuites/services/test_http_gate.py @@ -5,40 +5,47 @@ from time import sleep import allure import pytest - from common import COMPLEX_OBJ_SIZE from container import create_container from epoch import get_epoch, tick_epoch -from grpc_responses import OBJECT_NOT_FOUND, error_matches_status -from python_keywords.http_gate import (get_via_http_curl, get_via_http_gate, - get_via_http_gate_by_attribute, get_via_zip_http_gate, - upload_via_http_gate, upload_via_http_gate_curl) +from python_keywords.http_gate import ( + get_via_http_curl, + get_via_http_gate, + get_via_http_gate_by_attribute, + get_via_zip_http_gate, + upload_via_http_gate, + upload_via_http_gate_curl, +) from python_keywords.neofs_verbs import get_object, put_object from python_keywords.storage_policy import get_nodes_without_object from python_keywords.utility_keywords import generate_file, get_file_hash from utility import wait_for_gc_pass_on_storage_nodes from wellknown_acl import PUBLIC_ACL -logger = logging.getLogger('NeoLogger') +logger = logging.getLogger("NeoLogger") +OBJECT_NOT_FOUND_ERROR = "object not found" # For some reason object uploaded via http gateway is not immediately available for downloading # Until this issue is resolved we are waiting for some time before attempting to read an object # TODO: remove after https://github.com/nspcc-dev/neofs-http-gw/issues/176 is fixed OBJECT_UPLOAD_DELAY = 10 -@allure.link('https://github.com/nspcc-dev/neofs-http-gw#neofs-http-gateway', name='neofs-http-gateway') -@allure.link('https://github.com/nspcc-dev/neofs-http-gw#uploading', name='uploading') -@allure.link('https://github.com/nspcc-dev/neofs-http-gw#downloading', name='downloading') + +@allure.link( + "https://github.com/nspcc-dev/neofs-http-gw#neofs-http-gateway", name="neofs-http-gateway" +) +@allure.link("https://github.com/nspcc-dev/neofs-http-gw#uploading", name="uploading") +@allure.link("https://github.com/nspcc-dev/neofs-http-gw#downloading", name="downloading") @pytest.mark.http_gate class TestHttpGate: PLACEMENT_RULE = "REP 1 IN X CBF 1 SELECT 1 FROM * AS X" @pytest.fixture(scope="class", autouse=True) - @allure.title('[Class/Autouse]: Prepare wallet and deposit') + @allure.title("[Class/Autouse]: Prepare wallet and deposit") def prepare_wallet(self, prepare_wallet_and_deposit): TestHttpGate.wallet = prepare_wallet_and_deposit - @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): """ Test that object can be put using gRPC interface and get using HTTP. @@ -57,17 +64,17 @@ class TestHttpGate: cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE) - with allure.step('Put objects using gRPC'): + with allure.step("Put objects using gRPC"): oid_simple = put_object(wallet=self.wallet, path=file_path_simple, cid=cid) oid_large = put_object(wallet=self.wallet, path=file_path_large, cid=cid) for oid, file_path in ((oid_simple, file_path_simple), (oid_large, file_path_large)): self.get_object_and_verify_hashes(oid, file_path, self.wallet, cid) - @allure.link('https://github.com/nspcc-dev/neofs-http-gw#uploading', name='uploading') - @allure.link('https://github.com/nspcc-dev/neofs-http-gw#downloading', name='downloading') + @allure.link("https://github.com/nspcc-dev/neofs-http-gw#uploading", name="uploading") + @allure.link("https://github.com/nspcc-dev/neofs-http-gw#downloading", name="downloading") @pytest.mark.sanity - @allure.title('Test Put over HTTP, Get over HTTP') + @allure.title("Test Put over HTTP, Get over HTTP") def test_put_http_get_http(self): """ Test that object can be put and get using HTTP interface. @@ -84,23 +91,25 @@ class TestHttpGate: cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE) - with allure.step('Put objects using HTTP'): + with allure.step("Put objects using HTTP"): oid_simple = upload_via_http_gate(cid=cid, path=file_path_simple) oid_large = upload_via_http_gate(cid=cid, path=file_path_large) for oid, file_path in ((oid_simple, file_path_simple), (oid_large, file_path_large)): self.get_object_and_verify_hashes(oid, file_path, self.wallet, cid) - @allure.link('https://github.com/nspcc-dev/neofs-http-gw#by-attributes', name='download by attributes') - @allure.title('Test Put over HTTP, Get over HTTP with headers') + @allure.link( + "https://github.com/nspcc-dev/neofs-http-gw#by-attributes", name="download by attributes" + ) + @allure.title("Test Put over HTTP, Get over HTTP with headers") @pytest.mark.parametrize( - 'attributes', + "attributes", [ - {'fileName': 'simple_obj_filename'}, - {'file-Name': 'simple obj filename'}, - {'cat%jpeg': 'cat%jpeg'} + {"fileName": "simple_obj_filename"}, + {"file-Name": "simple obj filename"}, + {"cat%jpeg": "cat%jpeg"}, ], - ids=['simple', 'hyphen', 'percent'] + ids=["simple", "hyphen", "percent"], ) def test_put_http_get_http_with_headers(self, attributes: dict): """ @@ -118,7 +127,7 @@ class TestHttpGate: cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) file_path = generate_file() - with allure.step('Put objects using HTTP with attribute'): + with allure.step("Put objects using HTTP with attribute"): headers = self._attr_into_header(attributes) oid = upload_via_http_gate(cid=cid, path=file_path, headers=headers) @@ -126,7 +135,7 @@ class TestHttpGate: 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): cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) file_path = generate_file() @@ -136,14 +145,14 @@ class TestHttpGate: epochs = (curr_epoch, curr_epoch + 1, curr_epoch + 2, curr_epoch + 100) for epoch in epochs: - headers = {'X-Attribute-Neofs-Expiration-Epoch': str(epoch)} + headers = {"X-Attribute-Neofs-Expiration-Epoch": str(epoch)} - with allure.step('Put objects using HTTP with attribute Expiration-Epoch'): + with allure.step("Put objects using HTTP with attribute Expiration-Epoch"): oids.append(upload_via_http_gate(cid=cid, path=file_path, headers=headers)) - assert len(oids) == len(epochs), 'Expected all objects have been put successfully' + assert len(oids) == len(epochs), "Expected all objects have been put successfully" - with allure.step('All objects can be get'): + with allure.step("All objects can be get"): for oid in oids: get_via_http_gate(cid=cid, oid=oid) @@ -155,23 +164,21 @@ class TestHttpGate: for oid in expired_objects: self.try_to_get_object_and_expect_error( - cid=cid, - oid=oid, - error_pattern=OBJECT_NOT_FOUND + cid=cid, oid=oid, error_pattern=OBJECT_NOT_FOUND_ERROR ) - with allure.step('Other objects can be get'): + with allure.step("Other objects can be get"): for oid in not_expired_objects: get_via_http_gate(cid=cid, oid=oid) - @allure.title('Test Zip in HTTP header') + @allure.title("Test Zip in HTTP header") def test_zip_in_http(self): cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE) - common_prefix = 'my_files' + common_prefix = "my_files" - headers1 = {'X-Attribute-FilePath': f'{common_prefix}/file1'} - headers2 = {'X-Attribute-FilePath': f'{common_prefix}/file2'} + headers1 = {"X-Attribute-FilePath": f"{common_prefix}/file1"} + headers2 = {"X-Attribute-FilePath": f"{common_prefix}/file2"} upload_via_http_gate(cid=cid, path=file_path_simple, headers=headers1) upload_via_http_gate(cid=cid, path=file_path_large, headers=headers2) @@ -180,23 +187,23 @@ class TestHttpGate: dir_path = get_via_zip_http_gate(cid=cid, prefix=common_prefix) - with allure.step('Verify hashes'): - assert get_file_hash(f'{dir_path}/file1') == get_file_hash(file_path_simple) - assert get_file_hash(f'{dir_path}/file2') == get_file_hash(file_path_large) + with allure.step("Verify hashes"): + assert get_file_hash(f"{dir_path}/file1") == get_file_hash(file_path_simple) + assert get_file_hash(f"{dir_path}/file2") == get_file_hash(file_path_large) @pytest.mark.curl @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): """ This test checks upload and download using curl with 'large' object. Large is object with size up to 20Mb. """ cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) - obj_size = int(os.getenv('BIG_OBJ_SIZE', COMPLEX_OBJ_SIZE)) + obj_size = int(os.getenv("BIG_OBJ_SIZE", COMPLEX_OBJ_SIZE)) file_path = generate_file(obj_size) - with allure.step('Put objects using HTTP'): + with allure.step("Put objects using HTTP"): oid_gate = upload_via_http_gate(cid=cid, path=file_path) oid_curl = upload_via_http_gate_curl(cid=cid, filepath=file_path, large_object=True) @@ -204,7 +211,7 @@ class TestHttpGate: self.get_object_and_verify_hashes(oid_curl, file_path, self.wallet, cid, get_via_http_curl) @pytest.mark.curl - @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): """ Test checks upload and download over HTTP using curl utility. @@ -212,7 +219,7 @@ class TestHttpGate: cid = create_container(self.wallet, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL) file_path_simple, file_path_large = generate_file(), generate_file(COMPLEX_OBJ_SIZE) - with allure.step('Put objects using curl utility'): + with allure.step("Put objects using curl utility"): oid_simple = upload_via_http_gate_curl(cid=cid, filepath=file_path_simple) oid_large = upload_via_http_gate_curl(cid=cid, filepath=file_path_large) @@ -220,26 +227,29 @@ class TestHttpGate: self.get_object_and_verify_hashes(oid, file_path, self.wallet, cid, get_via_http_curl) @staticmethod - @allure.step('Try to get object and expect error') + @allure.step("Try to get object and expect error") def try_to_get_object_and_expect_error(cid: str, oid: str, error_pattern: str) -> None: try: get_via_http_gate(cid=cid, oid=oid) - raise AssertionError(f'Expected error on getting object with cid: {cid}') + raise AssertionError(f"Expected error on getting object with cid: {cid}") except Exception as err: - assert error_matches_status(err, error_pattern), \ - f'Expected {err} to match {error_pattern}' + assert error_pattern in err, f"Expected {err} to match {error_pattern}" @staticmethod - @allure.step('Verify object can be get using HTTP header attribute') + @allure.step("Verify object can be get using HTTP header attribute") def get_object_by_attr_and_verify_hashes(oid: str, file_name: str, cid: str, attrs: dict): got_file_path_http = get_via_http_gate(cid=cid, oid=oid) got_file_path_http_attr = get_via_http_gate_by_attribute(cid=cid, attribute=attrs) - TestHttpGate._assert_hashes_are_equal(file_name, got_file_path_http, got_file_path_http_attr) + TestHttpGate._assert_hashes_are_equal( + file_name, got_file_path_http, got_file_path_http_attr + ) @staticmethod - @allure.step('Verify object can be get using HTTP') - def get_object_and_verify_hashes(oid: str, file_name: str, wallet: str, cid: str, object_getter=None): + @allure.step("Verify object can be get using HTTP") + def get_object_and_verify_hashes( + oid: str, file_name: str, wallet: str, cid: str, object_getter=None + ): nodes = get_nodes_without_object(wallet=wallet, cid=cid, oid=oid) random_node = choice(nodes) object_getter = object_getter or get_via_http_gate @@ -251,11 +261,15 @@ class TestHttpGate: @staticmethod def _assert_hashes_are_equal(orig_file_name: str, got_file_1: str, got_file_2: str): - msg = 'Expected hashes are equal for files {f1} and {f2}' + msg = "Expected hashes are equal for files {f1} and {f2}" got_file_hash_http = get_file_hash(got_file_1) - assert get_file_hash(got_file_2) == got_file_hash_http, msg.format(f1=got_file_2, f2=got_file_1) - assert get_file_hash(orig_file_name) == got_file_hash_http, msg.format(f1=orig_file_name, f2=got_file_1) + assert get_file_hash(got_file_2) == got_file_hash_http, msg.format( + f1=got_file_2, f2=got_file_1 + ) + assert get_file_hash(orig_file_name) == got_file_hash_http, msg.format( + f1=orig_file_name, f2=got_file_1 + ) @staticmethod def _attr_into_header(attrs: dict) -> dict: - return {f'X-Attribute-{_key}': _value for _key, _value in attrs.items()} + return {f"X-Attribute-{_key}": _value for _key, _value in attrs.items()}