forked from TrueCloudLab/frostfs-testcases
[#363] Updates for sanity scope
Signed-off-by: a.berezin <a.berezin@yadro.com>
This commit is contained in:
parent
a841251e06
commit
35f60af47d
8 changed files with 14 additions and 88 deletions
|
@ -10,6 +10,7 @@ markers =
|
|||
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
|
||||
exclude_sanity: tests which should not be in sanity scope
|
||||
# controlling markers
|
||||
order: manual control of test order
|
||||
logs_after_session: Make the last test in session
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import logging
|
||||
import random
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
import allure
|
||||
import pytest
|
||||
from dateutil import parser
|
||||
from frostfs_testlib import plugins, reporter
|
||||
from frostfs_testlib.cli import FrostfsCli
|
||||
from frostfs_testlib.clients import AwsCliClient, Boto3ClientWrapper, S3ClientWrapper, S3HttpClient
|
||||
|
@ -22,7 +21,6 @@ from frostfs_testlib.steps.cli.object import get_netmap_netinfo
|
|||
from frostfs_testlib.steps.epoch import ensure_fresh_epoch
|
||||
from frostfs_testlib.storage.cluster import Cluster, ClusterNode
|
||||
from frostfs_testlib.storage.controllers.cluster_state_controller import ClusterStateController
|
||||
from frostfs_testlib.storage.dataclasses.frostfs_services import StorageNode
|
||||
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||
from frostfs_testlib.storage.dataclasses.policy import PlacementPolicy
|
||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||
|
@ -30,7 +28,7 @@ from frostfs_testlib.storage.grpc_operations.client_wrappers import CliClientWra
|
|||
from frostfs_testlib.storage.grpc_operations.interfaces import GrpcClientWrapper
|
||||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
from frostfs_testlib.testing.parallel import parallel
|
||||
from frostfs_testlib.testing.test_control import cached_fixture, run_optionally, wait_for_success
|
||||
from frostfs_testlib.testing.test_control import cached_fixture, run_optionally
|
||||
from frostfs_testlib.utils import env_utils, string_utils, version_utils
|
||||
from frostfs_testlib.utils.file_utils import TestFile, generate_file
|
||||
|
||||
|
@ -40,7 +38,6 @@ from ..resources.common import TEST_CYCLES_COUNT
|
|||
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
SERVICE_ACTIVE_TIME = 20
|
||||
WALLTETS_IN_POOL = 2
|
||||
|
||||
|
||||
|
@ -155,7 +152,11 @@ def complex_object_size(max_object_size: int) -> ObjectSize:
|
|||
# By default we want all tests to be executed with both object sizes
|
||||
# This can be overriden in choosen tests if needed
|
||||
@pytest.fixture(
|
||||
scope="session", params=[pytest.param("simple", marks=pytest.mark.simple), pytest.param("complex", marks=pytest.mark.complex)]
|
||||
scope="session",
|
||||
params=[
|
||||
pytest.param("simple", marks=[pytest.mark.simple, pytest.mark.exclude_sanity]),
|
||||
pytest.param("complex", marks=pytest.mark.complex),
|
||||
],
|
||||
)
|
||||
def object_size(simple_object_size: ObjectSize, complex_object_size: ObjectSize, request: pytest.FixtureRequest) -> ObjectSize:
|
||||
if request.param == "simple":
|
||||
|
@ -291,7 +292,7 @@ def credentials_provider(cluster: Cluster) -> CredentialsProvider:
|
|||
@pytest.fixture(
|
||||
scope="session",
|
||||
params=[
|
||||
pytest.param(AwsCliClient, marks=[pytest.mark.aws, pytest.mark.weekly]),
|
||||
pytest.param(AwsCliClient, marks=[pytest.mark.aws, pytest.mark.weekly, pytest.mark.exclude_sanity]),
|
||||
pytest.param(Boto3ClientWrapper, marks=[pytest.mark.boto3, pytest.mark.nightly]),
|
||||
],
|
||||
)
|
||||
|
@ -416,44 +417,11 @@ def session_start_time(configure_testlib):
|
|||
return start_time
|
||||
|
||||
|
||||
@allure.title("[Autouse/Session] After deploy healthcheck")
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
@run_optionally(optionals.OPTIONAL_AUTOUSE_FIXTURES_ENABLED)
|
||||
def after_deploy_healthcheck(cluster: Cluster):
|
||||
with reporter.step("Wait for cluster readiness after deploy"):
|
||||
parallel(readiness_on_node, cluster.cluster_nodes)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def rpc_endpoint(cluster: Cluster):
|
||||
return cluster.default_rpc_endpoint
|
||||
|
||||
|
||||
@wait_for_success(60 * SERVICE_ACTIVE_TIME * 3, 60, title="Wait for {cluster_node} readiness")
|
||||
def readiness_on_node(cluster_node: ClusterNode):
|
||||
if "skip_readiness_check" in cluster_node.host.config.attributes and cluster_node.host.config.attributes["skip_readiness_check"]:
|
||||
return
|
||||
|
||||
# TODO: Move to healtcheck classes
|
||||
svc_name = cluster_node.service(StorageNode).get_service_systemctl_name()
|
||||
with reporter.step(f"Check service {svc_name} is active"):
|
||||
result = cluster_node.host.get_shell().exec(f"systemctl is-active {svc_name}")
|
||||
assert "active" == result.stdout.strip(), f"Service {svc_name} should be in active state"
|
||||
|
||||
with reporter.step(f"Check service {svc_name} is active more than {SERVICE_ACTIVE_TIME} minutes"):
|
||||
result = cluster_node.host.get_shell().exec(f"systemctl show {svc_name} --property ActiveEnterTimestamp | cut -d '=' -f 2")
|
||||
start_time = parser.parse(result.stdout.strip())
|
||||
current_time = datetime.now(tz=timezone.utc)
|
||||
active_time = current_time - start_time
|
||||
|
||||
active_minutes = active_time.seconds // 60
|
||||
active_seconds = active_time.seconds - active_minutes * 60
|
||||
|
||||
assert active_time > timedelta(
|
||||
minutes=SERVICE_ACTIVE_TIME
|
||||
), f"Service should be in active state more than {SERVICE_ACTIVE_TIME} minutes, current {active_minutes}m:{active_seconds}s"
|
||||
|
||||
|
||||
@reporter.step("Prepare default user with wallet")
|
||||
@pytest.fixture(scope="session")
|
||||
@cached_fixture(optionals.OPTIONAL_CACHE_FIXTURES)
|
||||
|
|
|
@ -59,7 +59,7 @@ class TestContainer(ClusterTestBase):
|
|||
self.tick_epoch()
|
||||
wait_for_container_deletion(wallet, cid, self.shell, rpc_endpoint)
|
||||
|
||||
@allure.title("Delete container without force (name={name})")
|
||||
@allure.title("Delete container without force")
|
||||
@pytest.mark.smoke
|
||||
def test_container_deletion_no_force(self, container: str, default_wallet: WalletInfo, rpc_endpoint: str):
|
||||
with reporter.step("Delete container and check it was deleted"):
|
||||
|
@ -68,6 +68,7 @@ class TestContainer(ClusterTestBase):
|
|||
wait_for_container_deletion(default_wallet, container, self.shell, rpc_endpoint)
|
||||
|
||||
@allure.title("Parallel container creation and deletion")
|
||||
@pytest.mark.exclude_sanity
|
||||
def test_container_creation_deletion_parallel(self, default_wallet: WalletInfo, rpc_endpoint: str):
|
||||
containers_count = 3
|
||||
wallet = default_wallet
|
||||
|
|
|
@ -424,7 +424,6 @@ class TestMaintenanceMode(ClusterTestBase):
|
|||
with pytest.raises(RuntimeError, match=node_under_maintenance_error):
|
||||
put_object(default_wallet, file_path, cid, self.shell, endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("MAINTENANCE and OFFLINE mode transitions")
|
||||
def test_mode_transitions(
|
||||
self,
|
||||
|
|
|
@ -314,6 +314,7 @@ class TestObjectApi(ClusterTestBase):
|
|||
assert sorted(expected_oids) == sorted(result)
|
||||
|
||||
@allure.title("Search objects with removed items (obj_size={object_size})")
|
||||
@pytest.mark.exclude_sanity
|
||||
def test_object_search_should_return_tombstone_items(
|
||||
self,
|
||||
default_wallet: WalletInfo,
|
||||
|
|
|
@ -22,7 +22,6 @@ OBJECT_ATTRIBUTES = {"common_key": "common_value"}
|
|||
WAIT_FOR_REPLICATION = 60
|
||||
|
||||
# Adding failover mark because it may make cluster unhealthy
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.failover
|
||||
@pytest.mark.replication
|
||||
class TestReplication(ClusterTestBase):
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import allure
|
||||
import pytest
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.steps.cli.object import put_object_to_random_node
|
||||
from frostfs_testlib.steps.epoch import get_epoch
|
||||
from frostfs_testlib.steps.http_gate import (
|
||||
attr_into_header,
|
||||
|
@ -19,55 +18,12 @@ from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
|||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
from frostfs_testlib.utils.file_utils import TestFile, generate_file, get_file_hash
|
||||
|
||||
from ....helpers.container_request import REP_1_1_1_PUBLIC, REP_2_2_2_PUBLIC, requires_container
|
||||
from ....helpers.container_request import REP_2_2_2_PUBLIC, requires_container
|
||||
from ....helpers.utility import wait_for_gc_pass_on_storage_nodes
|
||||
|
||||
OBJECT_NOT_FOUND_ERROR = "not found"
|
||||
|
||||
|
||||
@allure.link(
|
||||
"https://git.frostfs.info/TrueCloudLab/frostfs-http-gw#frostfs-http-gateway",
|
||||
name="frostfs-http-gateway",
|
||||
)
|
||||
@allure.link("https://git.frostfs.info/TrueCloudLab/frostfs-http-gw#uploading", name="uploading")
|
||||
@allure.link("https://git.frostfs.info/TrueCloudLab/frostfs-http-gw#downloading", name="downloading")
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.http_gate
|
||||
class TestHttpGate(ClusterTestBase):
|
||||
@allure.title("Put over gRPC, Get over HTTP (object_size={object_size})")
|
||||
@requires_container(REP_1_1_1_PUBLIC)
|
||||
def test_put_grpc_get_http(self, default_wallet: WalletInfo, container: str, test_file: TestFile):
|
||||
"""
|
||||
Test that object can be put using gRPC interface and get using HTTP.
|
||||
|
||||
Steps:
|
||||
1. Create object.
|
||||
2. Put object using gRPC (frostfs-cli).
|
||||
3. Download object using HTTP gate (https://git.frostfs.info/TrueCloudLab/frostfs-http-gw#downloading).
|
||||
4. Get object using gRPC (frostfs-cli).
|
||||
5. Compare hashes for got object.
|
||||
6. Compare hashes for got and original objects.
|
||||
|
||||
Expected result:
|
||||
Hashes must be the same.
|
||||
"""
|
||||
|
||||
with reporter.step("Put object using gRPC"):
|
||||
object_id = put_object_to_random_node(default_wallet, test_file.path, container, self.shell, self.cluster)
|
||||
|
||||
with reporter.step("Get object and check hash"):
|
||||
verify_object_hash(
|
||||
object_id,
|
||||
test_file.path,
|
||||
default_wallet,
|
||||
container,
|
||||
self.shell,
|
||||
self.cluster.storage_nodes,
|
||||
self.cluster.cluster_nodes[0],
|
||||
)
|
||||
|
||||
|
||||
@allure.link(
|
||||
"https://git.frostfs.info/TrueCloudLab/frostfs-http-gw#frostfs-http-gateway",
|
||||
name="frostfs-http-gateway",
|
||||
|
|
|
@ -18,6 +18,7 @@ def _check_version_format(version):
|
|||
|
||||
|
||||
@allure.title("Check binaries versions")
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.check_binaries
|
||||
def test_binaries_versions(hosting: Hosting):
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue