Add new testmarks
Signed-off-by: Vladimir Avdeev <v.avdeev@yadro.com>
This commit is contained in:
parent
a7817304d5
commit
f9fa249cf2
21 changed files with 55 additions and 18 deletions
|
@ -136,3 +136,9 @@ the feature/topic you are going to implement.
|
||||||
# License
|
# License
|
||||||
|
|
||||||
- [GNU General Public License v3.0](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.
|
||||||
|
|
|
@ -7,22 +7,34 @@ log_cli_date_format = %Y-%m-%d %H:%M:%S
|
||||||
log_date_format = %H:%M:%S
|
log_date_format = %H:%M:%S
|
||||||
markers =
|
markers =
|
||||||
# special 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
|
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
|
# functional markers
|
||||||
container: tests for container creation
|
container: tests for container creation
|
||||||
grpc_api: standard gRPC API tests
|
grpc_api: standard gRPC API tests
|
||||||
http_gate: HTTP gate contract
|
http_gate: HTTP gate contract
|
||||||
s3_gate: S3 gate tests
|
s3_gate: All S3 gate tests
|
||||||
curl: tests for HTTP gate with curl utility
|
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)
|
long: long tests (with long execution time)
|
||||||
node_mgmt: neofs control commands
|
node_mgmt: neofs control commands
|
||||||
session_token: tests for operations with session token
|
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
|
storage_group: tests for storage groups
|
||||||
failover: tests for system recovery after a failure
|
failover: tests for system recovery after a failure
|
||||||
failover_panic: tests for system recovery after panic reboot of a node
|
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
|
add_nodes: add nodes to cluster
|
||||||
check_binaries: check neofs installed binaries versions
|
check_binaries: check neofs installed binaries versions
|
||||||
payments: tests for payment associated operations
|
payments: tests for payment associated operations
|
||||||
|
|
|
@ -50,6 +50,8 @@ deposit = 30
|
||||||
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
[SIMPLE_OBJ_SIZE, COMPLEX_OBJ_SIZE],
|
||||||
ids=["simple object", "complex object"],
|
ids=["simple object", "complex object"],
|
||||||
)
|
)
|
||||||
|
@pytest.mark.sanity
|
||||||
|
@pytest.mark.acl
|
||||||
@pytest.mark.storage_group
|
@pytest.mark.storage_group
|
||||||
class TestStorageGroup:
|
class TestStorageGroup:
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
|
|
|
@ -12,6 +12,7 @@ from wellknown_acl import PRIVATE_ACL_F, PUBLIC_ACL_F, READONLY_ACL_F
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
|
@pytest.mark.smoke
|
||||||
@pytest.mark.acl
|
@pytest.mark.acl
|
||||||
@pytest.mark.acl_basic
|
@pytest.mark.acl_basic
|
||||||
class TestACLBasic:
|
class TestACLBasic:
|
||||||
|
|
|
@ -26,7 +26,6 @@ from wellknown_acl import PUBLIC_ACL
|
||||||
|
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
@pytest.mark.acl
|
@pytest.mark.acl
|
||||||
@pytest.mark.acl_bearer
|
|
||||||
@pytest.mark.acl_filters
|
@pytest.mark.acl_filters
|
||||||
class TestEACLFilters:
|
class TestEACLFilters:
|
||||||
# SPEC: https://github.com/nspcc-dev/neofs-spec/blob/master/01-arch/07-acl.md
|
# SPEC: https://github.com/nspcc-dev/neofs-spec/blob/master/01-arch/07-acl.md
|
||||||
|
|
|
@ -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.parametrize("name", ["", "test-container"], ids=["No name", "Set particular name"])
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
|
@pytest.mark.smoke
|
||||||
@pytest.mark.container
|
@pytest.mark.container
|
||||||
def test_container_creation(client_shell, prepare_wallet_and_deposit, name):
|
def test_container_creation(client_shell, prepare_wallet_and_deposit, name):
|
||||||
scenario_title = f"with name {name}" if name else "without name"
|
scenario_title = f"with name {name}" if name else "without name"
|
||||||
|
|
|
@ -36,7 +36,7 @@ def restore_network(hosting: Hosting):
|
||||||
|
|
||||||
@allure.title("Block Storage node traffic")
|
@allure.title("Block Storage node traffic")
|
||||||
@pytest.mark.failover
|
@pytest.mark.failover
|
||||||
@pytest.mark.failover_net
|
@pytest.mark.failover_network
|
||||||
def test_block_storage_node_traffic(
|
def test_block_storage_node_traffic(
|
||||||
prepare_wallet_and_deposit, client_shell, require_multiple_hosts, hosting: Hosting
|
prepare_wallet_and_deposit, client_shell, require_multiple_hosts, hosting: Hosting
|
||||||
):
|
):
|
||||||
|
|
|
@ -14,7 +14,7 @@ logger = logging.getLogger("NeoLogger")
|
||||||
stopped_hosts = []
|
stopped_hosts = []
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
@allure.step("Return all stopped hosts")
|
@allure.step("Return all stopped hosts")
|
||||||
def after_run_return_all_stopped_hosts(hosting: Hosting):
|
def after_run_return_all_stopped_hosts(hosting: Hosting):
|
||||||
yield
|
yield
|
||||||
|
@ -42,6 +42,7 @@ def return_stopped_hosts(hosting: Hosting) -> None:
|
||||||
@allure.title("Lose and return storage node's host")
|
@allure.title("Lose and return storage node's host")
|
||||||
@pytest.mark.parametrize("hard_reboot", [True, False])
|
@pytest.mark.parametrize("hard_reboot", [True, False])
|
||||||
@pytest.mark.failover
|
@pytest.mark.failover
|
||||||
|
@pytest.mark.failover_reboot
|
||||||
def test_lose_storage_node_host(
|
def test_lose_storage_node_host(
|
||||||
prepare_wallet_and_deposit,
|
prepare_wallet_and_deposit,
|
||||||
client_shell,
|
client_shell,
|
||||||
|
@ -84,8 +85,8 @@ def test_lose_storage_node_host(
|
||||||
|
|
||||||
@allure.title("Panic storage node's host")
|
@allure.title("Panic storage node's host")
|
||||||
@pytest.mark.parametrize("sequence", [True, False])
|
@pytest.mark.parametrize("sequence", [True, False])
|
||||||
@pytest.mark.failover_panic
|
|
||||||
@pytest.mark.failover
|
@pytest.mark.failover
|
||||||
|
@pytest.mark.failover_panic
|
||||||
def test_panic_storage_node_host(
|
def test_panic_storage_node_host(
|
||||||
prepare_wallet_and_deposit,
|
prepare_wallet_and_deposit,
|
||||||
client_shell,
|
client_shell,
|
||||||
|
|
|
@ -346,6 +346,7 @@ def test_placement_policy_negative(
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason="We cover this scenario in failover tests")
|
@pytest.mark.skip(reason="We cover this scenario in failover tests")
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.node_mgmt
|
@pytest.mark.node_mgmt
|
||||||
@allure.title("NeoFS object replication on node failover")
|
@allure.title("NeoFS object replication on node failover")
|
||||||
def test_replication(
|
def test_replication(
|
||||||
|
|
|
@ -20,6 +20,7 @@ logger = logging.getLogger("NeoLogger")
|
||||||
DEPOSIT_AMOUNT = 30
|
DEPOSIT_AMOUNT = 30
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.payments
|
@pytest.mark.payments
|
||||||
@pytest.mark.skipif(FREE_STORAGE, reason="Test only works on public network with paid storage")
|
@pytest.mark.skipif(FREE_STORAGE, reason="Test only works on public network with paid storage")
|
||||||
class TestBalanceAccounting:
|
class TestBalanceAccounting:
|
||||||
|
|
|
@ -12,6 +12,8 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
|
@pytest.mark.acl
|
||||||
@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")
|
||||||
|
|
|
@ -14,7 +14,9 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
|
@pytest.mark.s3_gate_bucket
|
||||||
class TestS3GateBucket(TestS3GateBase):
|
class TestS3GateBucket(TestS3GateBase):
|
||||||
@allure.title("Test S3: Create Bucket with different ACL")
|
@allure.title("Test S3: Create Bucket with different ACL")
|
||||||
def test_s3_create_bucket_with_ACL(self):
|
def test_s3_create_bucket_with_ACL(self):
|
||||||
|
|
|
@ -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")
|
@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
|
||||||
|
@pytest.mark.s3_gate_base
|
||||||
class TestS3Gate(TestS3GateBase):
|
class TestS3Gate(TestS3GateBase):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@allure.title("Create two buckets")
|
@allure.title("Create two buckets")
|
||||||
|
@ -133,7 +135,6 @@ class TestS3Gate(TestS3GateBase):
|
||||||
s3_gate_bucket.head_bucket(self.s3_client, bucket_1)
|
s3_gate_bucket.head_bucket(self.s3_client, bucket_1)
|
||||||
|
|
||||||
@allure.title("Test S3 Object API")
|
@allure.title("Test S3 Object API")
|
||||||
@pytest.mark.sanity
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"file_type", ["simple", "large"], ids=["Simple object", "Large object"]
|
"file_type", ["simple", "large"], ids=["Simple object", "Large object"]
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
import os
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta
|
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
|
||||||
|
@ -19,7 +15,9 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
|
@pytest.mark.s3_gate_locking
|
||||||
@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")
|
||||||
|
|
|
@ -14,6 +14,7 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
@pytest.mark.s3_gate_multipart
|
@pytest.mark.s3_gate_multipart
|
||||||
class TestS3GateMultipart(TestS3GateBase):
|
class TestS3GateMultipart(TestS3GateBase):
|
||||||
|
|
|
@ -22,6 +22,8 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
|
@pytest.mark.s3_gate
|
||||||
@pytest.mark.s3_gate_object
|
@pytest.mark.s3_gate_object
|
||||||
class TestS3GateObject(TestS3GateBase):
|
class TestS3GateObject(TestS3GateBase):
|
||||||
@staticmethod
|
@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"
|
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
|
||||||
def test_s3_head_object(self):
|
def test_s3_head_object(self):
|
||||||
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_OBJ_SIZE)
|
||||||
|
|
|
@ -18,7 +18,9 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
|
@pytest.mark.s3_gate_tagging
|
||||||
class TestS3GateTagging(TestS3GateBase):
|
class TestS3GateTagging(TestS3GateBase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_tags(count: int) -> Tuple[list, list]:
|
def create_tags(count: int) -> Tuple[list, list]:
|
||||||
|
|
|
@ -14,7 +14,9 @@ def pytest_generate_tests(metafunc):
|
||||||
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
metafunc.parametrize("s3_client", ["aws cli", "boto3"], indirect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.s3_gate
|
@pytest.mark.s3_gate
|
||||||
|
@pytest.mark.s3_gate_versioning
|
||||||
class TestS3GateVersioning(TestS3GateBase):
|
class TestS3GateVersioning(TestS3GateBase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def object_key_from_file_path(full_path: str) -> str:
|
def object_key_from_file_path(full_path: str) -> str:
|
||||||
|
|
|
@ -14,6 +14,7 @@ logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
|
||||||
@allure.title("Check binaries versions")
|
@allure.title("Check binaries versions")
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.check_binaries
|
@pytest.mark.check_binaries
|
||||||
@pytest.mark.skip("Skipped due to https://j.yadro.com/browse/OBJECT-628")
|
@pytest.mark.skip("Skipped due to https://j.yadro.com/browse/OBJECT-628")
|
||||||
def test_binaries_versions(request, hosting: Hosting):
|
def test_binaries_versions(request, hosting: Hosting):
|
||||||
|
|
|
@ -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#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#downloading", name="downloading")
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.http_gate
|
@pytest.mark.http_gate
|
||||||
class TestHttpGate:
|
class TestHttpGate:
|
||||||
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"
|
||||||
|
@ -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#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#downloading", name="downloading")
|
||||||
@pytest.mark.sanity
|
|
||||||
@allure.title("Test Put over HTTP, Get over HTTP")
|
@allure.title("Test Put over HTTP, Get over HTTP")
|
||||||
|
@pytest.mark.smoke
|
||||||
def test_put_http_get_http(self, client_shell):
|
def test_put_http_get_http(self, client_shell):
|
||||||
"""
|
"""
|
||||||
Test that object can be put and get using HTTP interface.
|
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}/file1") == get_file_hash(file_path_simple)
|
||||||
assert get_file_hash(f"{dir_path}/file2") == get_file_hash(file_path_large)
|
assert get_file_hash(f"{dir_path}/file2") == get_file_hash(file_path_large)
|
||||||
|
|
||||||
@pytest.mark.curl
|
|
||||||
@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, client_shell):
|
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(
|
cid = create_container(
|
||||||
self.wallet, shell=client_shell, rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL
|
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,
|
object_getter=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, client_shell):
|
def test_put_http_get_http_curl(self, client_shell):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,6 +13,7 @@ from python_keywords.session_token import create_session_token
|
||||||
|
|
||||||
|
|
||||||
@allure.title("Test Object Operations with Session Token")
|
@allure.title("Test Object Operations with Session Token")
|
||||||
|
@pytest.mark.sanity
|
||||||
@pytest.mark.session_token
|
@pytest.mark.session_token
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"object_size",
|
"object_size",
|
||||||
|
|
Loading…
Reference in a new issue