diff --git a/README.md b/README.md index 7a37541b..1252ef5b 100644 --- a/README.md +++ b/README.md @@ -136,3 +136,9 @@ the feature/topic you are going to implement. # License - [GNU General Public License v3.0](LICENSE) + +## Pytest marks + +Custom pytest marks used in tests: +* `sanity` - Tests must be runs in sanity testruns. +* `smoke` - Tests must be runs in smoke testruns. diff --git a/pytest_tests/pytest.ini b/pytest_tests/pytest.ini index 97f3a80a..034d99bc 100644 --- a/pytest_tests/pytest.ini +++ b/pytest_tests/pytest.ini @@ -7,22 +7,34 @@ log_cli_date_format = %Y-%m-%d %H:%M:%S log_date_format = %H:%M:%S markers = # special markers - sanity: small tests subset staging: test to be excluded from run in verifier/pr-validation/sanity jobs and run test in staging job + sanity: test runs in sanity testrun + smoke: test runs in smoke testrun # functional markers container: tests for container creation grpc_api: standard gRPC API tests http_gate: HTTP gate contract - s3_gate: S3 gate tests - curl: tests for HTTP gate with curl utility + s3_gate: All S3 gate tests + s3_gate_base: Base S3 gate tests + s3_gate_bucket: Bucket S3 gate tests + s3_gate_locking: Locking S3 gate tests + s3_gate_multipart: S3 gate tests with multipart object + s3_gate_object: Object S3 gate tests + s3_gate_tagging: Tagging S3 gate tests + s3_gate_versioning: Versioning S3 gate tests long: long tests (with long execution time) node_mgmt: neofs control commands session_token: tests for operations with session token - acl: tests for basic and extended ACL + acl: All tests for ACL + acl_basic: tests for basic ACL + acl_bearer: tests for ACL with bearer + acl_extended: tests for extended ACL + acl_filters: tests for extended ACL with filters and headers storage_group: tests for storage groups failover: tests for system recovery after a failure failover_panic: tests for system recovery after panic reboot of a node - failover_net: tests for network failure + failover_network: tests for network failure + failover_reboot: tests for system recovery after reboot of a node add_nodes: add nodes to cluster check_binaries: check neofs installed binaries versions payments: tests for payment associated operations diff --git a/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py b/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py index 8dbaed01..467ce9cc 100644 --- a/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py +++ b/pytest_tests/testsuites/acl/storage_group/test_storagegroup.py @@ -50,6 +50,8 @@ deposit = 30 [SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE], ids=["simple object", "complex object"], ) +@pytest.mark.sanity +@pytest.mark.acl @pytest.mark.storage_group class TestStorageGroup: @pytest.fixture(autouse=True) diff --git a/pytest_tests/testsuites/acl/test_acl.py b/pytest_tests/testsuites/acl/test_acl.py index 33b06812..541457eb 100644 --- a/pytest_tests/testsuites/acl/test_acl.py +++ b/pytest_tests/testsuites/acl/test_acl.py @@ -12,6 +12,7 @@ from wellknown_acl import PRIVATE_ACL_F, PUBLIC_ACL_F, READONLY_ACL_F @pytest.mark.sanity +@pytest.mark.smoke @pytest.mark.acl @pytest.mark.acl_basic class TestACLBasic: diff --git a/pytest_tests/testsuites/acl/test_eacl_filters.py b/pytest_tests/testsuites/acl/test_eacl_filters.py index 0c860cc3..39831531 100644 --- a/pytest_tests/testsuites/acl/test_eacl_filters.py +++ b/pytest_tests/testsuites/acl/test_eacl_filters.py @@ -26,7 +26,6 @@ from wellknown_acl import PUBLIC_ACL @pytest.mark.sanity @pytest.mark.acl -@pytest.mark.acl_bearer @pytest.mark.acl_filters class TestEACLFilters: # SPEC: https://github.com/nspcc-dev/neofs-spec/blob/master/01-arch/07-acl.md diff --git a/pytest_tests/testsuites/container/test_container.py b/pytest_tests/testsuites/container/test_container.py index 16d1a863..581d34fa 100644 --- a/pytest_tests/testsuites/container/test_container.py +++ b/pytest_tests/testsuites/container/test_container.py @@ -17,6 +17,7 @@ from wellknown_acl import PRIVATE_ACL_F @pytest.mark.parametrize("name", ["", "test-container"], ids=["No name", "Set particular name"]) @pytest.mark.sanity +@pytest.mark.smoke @pytest.mark.container def test_container_creation(client_shell, prepare_wallet_and_deposit, name): scenario_title = f"with name {name}" if name else "without name" diff --git a/pytest_tests/testsuites/failovers/test_failover_network.py b/pytest_tests/testsuites/failovers/test_failover_network.py index 5b02a57f..98aed8fd 100644 --- a/pytest_tests/testsuites/failovers/test_failover_network.py +++ b/pytest_tests/testsuites/failovers/test_failover_network.py @@ -36,7 +36,7 @@ def restore_network(hosting: Hosting): @allure.title("Block Storage node traffic") @pytest.mark.failover -@pytest.mark.failover_net +@pytest.mark.failover_network def test_block_storage_node_traffic( prepare_wallet_and_deposit, client_shell, require_multiple_hosts, hosting: Hosting ): diff --git a/pytest_tests/testsuites/failovers/test_failover_storage.py b/pytest_tests/testsuites/failovers/test_failover_storage.py index cafc6d0b..08eb95dd 100644 --- a/pytest_tests/testsuites/failovers/test_failover_storage.py +++ b/pytest_tests/testsuites/failovers/test_failover_storage.py @@ -14,7 +14,7 @@ logger = logging.getLogger("NeoLogger") stopped_hosts = [] -@pytest.fixture(autouse=True) +@pytest.fixture(scope="function", autouse=True) @allure.step("Return all stopped hosts") def after_run_return_all_stopped_hosts(hosting: Hosting): yield @@ -42,6 +42,7 @@ def return_stopped_hosts(hosting: Hosting) -> None: @allure.title("Lose and return storage node's host") @pytest.mark.parametrize("hard_reboot", [True, False]) @pytest.mark.failover +@pytest.mark.failover_reboot def test_lose_storage_node_host( prepare_wallet_and_deposit, client_shell, @@ -84,8 +85,8 @@ def test_lose_storage_node_host( @allure.title("Panic storage node's host") @pytest.mark.parametrize("sequence", [True, False]) -@pytest.mark.failover_panic @pytest.mark.failover +@pytest.mark.failover_panic def test_panic_storage_node_host( prepare_wallet_and_deposit, client_shell, diff --git a/pytest_tests/testsuites/network/test_node_management.py b/pytest_tests/testsuites/network/test_node_management.py index c97f3274..3065ef40 100644 --- a/pytest_tests/testsuites/network/test_node_management.py +++ b/pytest_tests/testsuites/network/test_node_management.py @@ -346,6 +346,7 @@ def test_placement_policy_negative( @pytest.mark.skip(reason="We cover this scenario in failover tests") +@pytest.mark.sanity @pytest.mark.node_mgmt @allure.title("NeoFS object replication on node failover") def test_replication( diff --git a/pytest_tests/testsuites/payment/test_balance.py b/pytest_tests/testsuites/payment/test_balance.py index 717c33eb..ac52e3bb 100644 --- a/pytest_tests/testsuites/payment/test_balance.py +++ b/pytest_tests/testsuites/payment/test_balance.py @@ -20,6 +20,7 @@ logger = logging.getLogger("NeoLogger") DEPOSIT_AMOUNT = 30 +@pytest.mark.sanity @pytest.mark.payments @pytest.mark.skipif(FREE_STORAGE, reason="Test only works on public network with paid storage") class TestBalanceAccounting: diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py b/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py index de51684c..9e3fca2f 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py @@ -12,6 +12,8 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity +@pytest.mark.acl @pytest.mark.s3_gate class TestS3GateACL(TestS3GateBase): @allure.title("Test S3: Object ACL") diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py b/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py index fecdd821..e4836213 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py @@ -14,7 +14,9 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity @pytest.mark.s3_gate +@pytest.mark.s3_gate_bucket class TestS3GateBucket(TestS3GateBase): @allure.title("Test S3: Create Bucket with different ACL") def test_s3_create_bucket_with_ACL(self): diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py index 62948100..f42f074b 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py @@ -34,7 +34,9 @@ def pytest_generate_tests(metafunc): @allure.link("https://github.com/nspcc-dev/neofs-s3-gw#neofs-s3-gateway", name="neofs-s3-gateway") +@pytest.mark.sanity @pytest.mark.s3_gate +@pytest.mark.s3_gate_base class TestS3Gate(TestS3GateBase): @pytest.fixture @allure.title("Create two buckets") @@ -133,7 +135,6 @@ class TestS3Gate(TestS3GateBase): s3_gate_bucket.head_bucket(self.s3_client, bucket_1) @allure.title("Test S3 Object API") - @pytest.mark.sanity @pytest.mark.parametrize( "file_type", ["simple", "large"], ids=["Simple object", "Large object"] ) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py b/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py index 0c7e9b21..bafb2ac4 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py @@ -1,9 +1,5 @@ -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 pytest @@ -19,7 +15,9 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity @pytest.mark.s3_gate +@pytest.mark.s3_gate_locking @pytest.mark.parametrize("version_id", [None, "second"]) class TestS3GateLocking(TestS3GateBase): @allure.title("Test S3: Checking the operation of retention period & legal lock on the object") diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py b/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py index 0c6c5bd9..4d691807 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py @@ -14,6 +14,7 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity @pytest.mark.s3_gate @pytest.mark.s3_gate_multipart class TestS3GateMultipart(TestS3GateBase): diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py index 8f5ef5fe..3ff82635 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py @@ -22,6 +22,8 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity +@pytest.mark.s3_gate @pytest.mark.s3_gate_object class TestS3GateObject(TestS3GateBase): @staticmethod @@ -473,6 +475,7 @@ class TestS3GateObject(TestS3GateBase): 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") + @pytest.mark.smoke def test_s3_head_object(self): object_metadata = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"} file_path = generate_file(COMPLEX_OBJ_SIZE) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py b/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py index c12b0e62..3bf190f5 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py @@ -18,7 +18,9 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity @pytest.mark.s3_gate +@pytest.mark.s3_gate_tagging class TestS3GateTagging(TestS3GateBase): @staticmethod def create_tags(count: int) -> Tuple[list, list]: diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py b/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py index f50c640f..e0cd1584 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py @@ -14,7 +14,9 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True) +@pytest.mark.sanity @pytest.mark.s3_gate +@pytest.mark.s3_gate_versioning class TestS3GateVersioning(TestS3GateBase): @staticmethod def object_key_from_file_path(full_path: str) -> str: diff --git a/pytest_tests/testsuites/services/test_binaries.py b/pytest_tests/testsuites/services/test_binaries.py index 5800f610..80582940 100644 --- a/pytest_tests/testsuites/services/test_binaries.py +++ b/pytest_tests/testsuites/services/test_binaries.py @@ -14,6 +14,7 @@ logger = logging.getLogger("NeoLogger") @allure.title("Check binaries versions") +@pytest.mark.sanity @pytest.mark.check_binaries @pytest.mark.skip("Skipped due to https://j.yadro.com/browse/OBJECT-628") def test_binaries_versions(request, hosting: Hosting): diff --git a/pytest_tests/testsuites/services/test_http_gate.py b/pytest_tests/testsuites/services/test_http_gate.py index 314ab7e9..055a795d 100644 --- a/pytest_tests/testsuites/services/test_http_gate.py +++ b/pytest_tests/testsuites/services/test_http_gate.py @@ -37,6 +37,7 @@ OBJECT_UPLOAD_DELAY = 10 ) @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 @pytest.mark.http_gate class TestHttpGate: PLACEMENT_RULE = "REP 1 IN X CBF 1 SELECT 1 FROM * AS X" @@ -80,8 +81,8 @@ class TestHttpGate: @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") + @pytest.mark.smoke def test_put_http_get_http(self, client_shell): """ Test that object can be put and get using HTTP interface. @@ -206,12 +207,12 @@ class TestHttpGate: 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") def test_put_http_get_http_large_file(self, client_shell): """ - This test checks upload and download using curl with 'large' object. Large is object with size up to 20Mb. + This test checks upload and download using curl with 'large' object. + Large is object with size up to 20Mb. """ cid = create_container( self.wallet, shell=client_shell, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL @@ -234,7 +235,6 @@ class TestHttpGate: object_getter=get_via_http_curl, ) - @pytest.mark.curl @allure.title("Test Put/Get over HTTP using Curl utility") def test_put_http_get_http_curl(self, client_shell): """ diff --git a/pytest_tests/testsuites/session_token/test_object_session_token.py b/pytest_tests/testsuites/session_token/test_object_session_token.py index 1daff750..ee45f26d 100644 --- a/pytest_tests/testsuites/session_token/test_object_session_token.py +++ b/pytest_tests/testsuites/session_token/test_object_session_token.py @@ -13,6 +13,7 @@ from python_keywords.session_token import create_session_token @allure.title("Test Object Operations with Session Token") +@pytest.mark.sanity @pytest.mark.session_token @pytest.mark.parametrize( "object_size",