diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py deleted file mode 100644 index db3bfe1a6..000000000 --- a/tests/integration/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright 2023 Canonical Ltd. -# See LICENSE file for licensing details. diff --git a/tests/integration/backup_tests/test_backups.py b/tests/integration/backup_tests/test_backups.py index 74f69a004..1d8634998 100644 --- a/tests/integration/backup_tests/test_backups.py +++ b/tests/integration/backup_tests/test_backups.py @@ -11,7 +11,7 @@ from pytest_operator.plugin import OpsTest from tenacity import RetryError, Retrying, stop_after_delay, wait_fixed -from tests.integration.helpers import get_app_name +from ..helpers import get_app_name from ..ha_tests import helpers as ha_helpers from . import helpers diff --git a/tests/integration/sharding_tests/test_sharding_backups.py b/tests/integration/sharding_tests/test_sharding_backups.py new file mode 100644 index 000000000..065f21f4d --- /dev/null +++ b/tests/integration/sharding_tests/test_sharding_backups.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +# Copyright 2024 Canonical Ltd. +# See LICENSE file for licensing details. + +import secrets +import string + +import pytest +from pytest_operator.plugin import OpsTest +from tenacity import RetryError, Retrying, stop_after_delay, wait_fixed + +from ..backup_tests import helpers as backup_helpers + +S3_APP_NAME = "s3-integrator" +SHARD_ONE_APP_NAME = "shard-one" +SHARD_TWO_APP_NAME = "shard-two" +SHARD_APPS = [SHARD_ONE_APP_NAME, SHARD_TWO_APP_NAME] +CONFIG_SERVER_APP_NAME = "config-server-one" +SHARD_REL_NAME = "sharding" +CONFIG_SERVER_REL_NAME = "config-server" +S3_REL_NAME = "s3-credentials" +TIMEOUT = 10 * 60 + + +@pytest.mark.group(1) +@pytest.mark.abort_on_fail +async def test_build_and_deploy(ops_test: OpsTest) -> None: + """Build and deploy a sharded cluster.""" + my_charm = await ops_test.build_charm(".") + await ops_test.model.deploy( + my_charm, + num_units=2, + config={"role": "config-server"}, + application_name=CONFIG_SERVER_APP_NAME, + ) + await ops_test.model.deploy( + my_charm, num_units=2, config={"role": "shard"}, application_name=SHARD_ONE_APP_NAME + ) + await ops_test.model.deploy( + my_charm, num_units=1, config={"role": "shard"}, application_name=SHARD_TWO_APP_NAME + ) + + # deploy the s3 integrator charm + await ops_test.model.deploy(S3_APP_NAME, channel="edge") + + await ops_test.model.wait_for_idle( + apps=[S3_APP_NAME, CONFIG_SERVER_APP_NAME, SHARD_ONE_APP_NAME, SHARD_TWO_APP_NAME], + idle_period=20, + raise_on_blocked=False, + timeout=TIMEOUT, + raise_on_error=False, + ) + + +@pytest.mark.group(1) +async def test_set_credentials_in_cluster(ops_test: OpsTest) -> None: + """Tests that sharded cluster can be configured for s3 configurations.""" + await backup_helpers.set_credentials(ops_test, cloud="AWS") + choices = string.ascii_letters + string.digits + unique_path = "".join([secrets.choice(choices) for _ in range(4)]) + configuration_parameters = { + "bucket": "data-charms-testing", + "path": f"mongodb-vm/test-{unique_path}", + "endpoint": "https://s3.amazonaws.com", + "region": "us-east-1", + } + + # apply new configuration options + await ops_test.model.applications[S3_APP_NAME].set_config(configuration_parameters) + await ops_test.model.wait_for_idle(apps=[S3_APP_NAME], status="active", timeout=TIMEOUT) + + # provide config-server to entire cluster and s3-integrator to config-server - integrations + # made in succession to test race conditions. + await ops_test.model.integrate( + f"{S3_APP_NAME}:{S3_REL_NAME}", + f"{CONFIG_SERVER_APP_NAME}:{S3_REL_NAME}", + ) + await ops_test.model.integrate( + f"{SHARD_ONE_APP_NAME}:{SHARD_REL_NAME}", + f"{CONFIG_SERVER_APP_NAME}:{CONFIG_SERVER_REL_NAME}", + ) + await ops_test.model.integrate( + f"{SHARD_TWO_APP_NAME}:{SHARD_REL_NAME}", + f"{CONFIG_SERVER_APP_NAME}:{CONFIG_SERVER_REL_NAME}", + ) + + await ops_test.model.wait_for_idle( + apps=[ + CONFIG_SERVER_APP_NAME, + SHARD_ONE_APP_NAME, + SHARD_TWO_APP_NAME, + ], + idle_period=20, + status="active", + timeout=TIMEOUT, + ) + + +@pytest.mark.group(1) +async def test_shard_cannot_integrate_s3(ops_test: OpsTest) -> None: + await ops_test.model.integrate( + f"{SHARD_ONE_APP_NAME}:{S3_REL_NAME}", + f"{S3_APP_NAME}:{S3_REL_NAME}", + ) + await ops_test.model.wait_for_idle( + apps=[ + SHARD_ONE_APP_NAME, + ], + idle_period=20, + status="blocked", + timeout=TIMEOUT, + ) diff --git a/tox.ini b/tox.ini index 80f8ec280..9dbbe8523 100644 --- a/tox.ini +++ b/tox.ini @@ -14,10 +14,8 @@ all_path = {[vars]src_path} {[vars]tests_path} {[vars]mongodb_lib_path} [testenv] set_env = - PYTHONPATH = {tox_root}/lib:{[vars]src_path} - PYTHONBREAKPOINT=ipdb.set_trace + PYTHONPATH = {[vars]src_path}:{tox_root}/lib PY_COLORS=1 - PYTHONDONTWRITEBYTECODE=1 pass_env = PYTHONPATH CHARM_BUILD_DIR