Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DPE-3083] Make integration tests work with existing cluster #324

Merged
merged 27 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
805c672
Ha tests update
dmitry-ratushnyy Jan 4, 2024
fd052ba
Tls tests
dmitry-ratushnyy Jan 4, 2024
18950e5
Metrics tests
dmitry-ratushnyy Jan 4, 2024
31136df
Metrics tests
dmitry-ratushnyy Jan 4, 2024
a9456d9
Charm integration
dmitry-ratushnyy Jan 4, 2024
cb4258e
Fix lint errors
dmitry-ratushnyy Jan 4, 2024
6018b6e
Fix for HA and relations tests
dmitry-ratushnyy Jan 5, 2024
10a2f4e
Reformat files
dmitry-ratushnyy Jan 5, 2024
5f1b847
Add logger for helpers
dmitry-ratushnyy Jan 5, 2024
0823a37
Use 'integrate' instead of 'add_relation'
dmitry-ratushnyy Jan 5, 2024
7e40e13
Fix lint errors
dmitry-ratushnyy Jan 5, 2024
58bafc6
Fix relation tests
dmitry-ratushnyy Jan 5, 2024
00c0843
Fix sharding tests
dmitry-ratushnyy Jan 5, 2024
2eb0f55
Fixes for tls tests
dmitry-ratushnyy Jan 6, 2024
2484a3a
HA tests WIP
dmitry-ratushnyy Jan 6, 2024
5d69abd
Fixed tests
dmitry-ratushnyy Jan 7, 2024
0cbc0fc
Remove non-needed param
dmitry-ratushnyy Jan 8, 2024
84cf1e5
WIP: Fix backup tests
dmitry-ratushnyy Jan 8, 2024
db8c87a
Fix lint issue
dmitry-ratushnyy Jan 8, 2024
08b0bca
fix relation tests
MiaAltieri Jan 8, 2024
38e98d8
pass db name
MiaAltieri Jan 8, 2024
908d83c
tests run on a provided cluster
MiaAltieri Jan 9, 2024
0b0e627
Merge branch '6/edge' into DPE-3083
MiaAltieri Jan 9, 2024
d96e174
PR feedback
MiaAltieri Jan 11, 2024
f683365
Merge branch '6/edge' into DPE-3083
MiaAltieri Jan 11, 2024
c632e76
run all backup tests
MiaAltieri Jan 11, 2024
6a11f20
Merge branch '6/edge' into DPE-3083
MiaAltieri Jan 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 6 additions & 23 deletions tests/integration/backup_tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from tenacity import RetryError, Retrying, stop_after_attempt, wait_fixed

from ..ha_tests import helpers as ha_helpers
from ..helpers import get_app_name

S3_APP_NAME = "s3-integrator"
TIMEOUT = 10 * 60
Expand Down Expand Up @@ -62,30 +63,12 @@ async def create_and_verify_backup(ops_test: OpsTest) -> None:

async def get_leader_unit(ops_test: OpsTest, db_app_name=None) -> ops.model.Unit:
"""Returns the leader unit of the database charm."""
db_app_name = db_app_name or await app_name(ops_test)
db_app_name = db_app_name or await get_app_name(ops_test)
for unit in ops_test.model.applications[db_app_name].units:
if await unit.is_leader_from_status():
return unit


async def app_name(ops_test: OpsTest) -> str:
"""Returns the name of the cluster running MongoDB.

This is important since not all deployments of the MongoDB charm have the application name
"mongodb".

Note: if multiple clusters are running MongoDB this will return the one first found.
"""
status = await ops_test.model.get_status()
for app in ops_test.model.applications:
# note that format of the charm field is not exactly "mongodb" but instead takes the form
# of `local:focal/mongodb-6`
if "mongodb" in status["applications"][app]["charm"]:
return app

return None


async def count_logical_backups(db_unit: ops.model.Unit) -> int:
"""Count the number of logical backups."""
action = await db_unit.run_action(action_name="list-backups")
Expand Down Expand Up @@ -142,11 +125,11 @@ def is_relation_joined(ops_test: OpsTest, endpoint_one: str, endpoint_two: str)

async def insert_unwanted_data(ops_test: OpsTest) -> None:
"""Inserts the data into the MongoDB cluster via primary replica."""
app = await app_name(ops_test)
ip_addresses = [unit.public_address for unit in ops_test.model.applications[app].units]
app_name = await get_app_name(ops_test)
ip_addresses = [unit.public_address for unit in ops_test.model.applications[app_name].units]
primary = (await ha_helpers.replica_set_primary(ip_addresses, ops_test)).public_address
password = await ha_helpers.get_password(ops_test, app)
client = MongoClient(ha_helpers.unit_uri(primary, password, app), directConnection=True)
password = await ha_helpers.get_password(ops_test, app_name)
client = MongoClient(ha_helpers.unit_uri(primary, password, app_name), directConnection=True)
db = client["new-db"]
test_collection = db["test_collection"]
test_collection.insert_one({"unwanted_data": "bad data 1"})
Expand Down
34 changes: 21 additions & 13 deletions tests/integration/backup_tests/test_backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.
import asyncio
import logging
import secrets
import string
import time
Expand All @@ -10,6 +11,8 @@
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 ..ha_tests import helpers as ha_helpers
from . import helpers

Expand All @@ -18,6 +21,8 @@
ENDPOINT = "s3-credentials"
NEW_CLUSTER = "new-mongodb"

logger = logging.getLogger(__name__)


@pytest.fixture()
async def continuous_writes_to_db(ops_test: OpsTest):
Expand All @@ -43,7 +48,7 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
"""Build and deploy one unit of MongoDB."""
# it is possible for users to provide their own cluster for testing. Hence check if there
# is a pre-existing cluster.
if not await helpers.app_name(ops_test):
if not await get_app_name(ops_test):
db_charm = await ops_test.build_charm(".")
await ops_test.model.deploy(db_charm, num_units=3)

Expand All @@ -56,7 +61,7 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
@pytest.mark.abort_on_fail
async def test_blocked_incorrect_creds(ops_test: OpsTest) -> None:
"""Verifies that the charm goes into blocked status when s3 creds are incorrect."""
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)

# set incorrect s3 credentials
s3_integrator_unit = ops_test.model.applications[S3_APP_NAME].units[0]
Expand Down Expand Up @@ -86,7 +91,7 @@ async def test_blocked_incorrect_creds(ops_test: OpsTest) -> None:
@pytest.mark.abort_on_fail
async def test_blocked_incorrect_conf(ops_test: OpsTest) -> None:
"""Verifies that the charm goes into blocked status when s3 config options are incorrect."""
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)

# set correct AWS credentials for s3 storage but incorrect configs
await helpers.set_credentials(ops_test, cloud="AWS")
Expand All @@ -105,7 +110,7 @@ async def test_blocked_incorrect_conf(ops_test: OpsTest) -> None:
@pytest.mark.abort_on_fail
async def test_ready_correct_conf(ops_test: OpsTest) -> None:
"""Verifies charm goes into active status when s3 config and creds options are correct."""
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)
choices = string.ascii_letters + string.digits
unique_path = "".join([secrets.choice(choices) for _ in range(4)])
configuration_parameters = {
Expand All @@ -127,16 +132,19 @@ async def test_ready_correct_conf(ops_test: OpsTest) -> None:

@pytest.mark.abort_on_fail
async def test_create_and_list_backups(ops_test: OpsTest) -> None:
db_unit = await helpers.get_leader_unit(ops_test)

db_app_name = await get_app_name(ops_test)
leader_unit = await helpers.get_leader_unit(ops_test, db_app_name=db_app_name)
await helpers.set_credentials(ops_test, cloud="AWS")
# verify backup list works
action = await db_unit.run_action(action_name="list-backups")
logger.error("!!!!! test_create_and_list_backups >>> %s", leader_unit)
action = await leader_unit.run_action(action_name="list-backups")
list_result = await action.wait()
logger.error("!!!!! test_create_and_list_backups >>> %s", list_result.results)
backups = list_result.results["backups"]
assert backups, "backups not outputted"

# verify backup is started
action = await db_unit.run_action(action_name="create-backup")
action = await leader_unit.run_action(action_name="create-backup")
backup_result = await action.wait()
assert "backup started" in backup_result.results["backup-status"], "backup didn't start"

Expand All @@ -147,7 +155,7 @@ async def test_create_and_list_backups(ops_test: OpsTest) -> None:
try:
for attempt in Retrying(stop=stop_after_delay(20), wait=wait_fixed(3)):
with attempt:
backups = await helpers.count_logical_backups(db_unit)
backups = await helpers.count_logical_backups(leader_unit)
assert backups == 1
except RetryError:
assert backups == 1, "Backup not created."
Expand All @@ -161,7 +169,7 @@ async def test_multi_backup(ops_test: OpsTest, continuous_writes_to_db) -> None:
from AWS to GCP. This test verifies that the first backup in AWS is made, the second backup
in GCP is made, and that before the second backup is made that pbm correctly resyncs.
"""
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)
db_unit = await helpers.get_leader_unit(ops_test)

# create first backup once ready
Expand Down Expand Up @@ -247,7 +255,7 @@ async def test_restore(ops_test: OpsTest, add_writes_to_db) -> None:
assert number_writes > 0, "no writes to backup"

# create a backup in the AWS bucket
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)
db_unit = await helpers.get_leader_unit(ops_test)
prev_backups = await helpers.count_logical_backups(db_unit)
action = await db_unit.run_action(action_name="create-backup")
Expand Down Expand Up @@ -296,7 +304,7 @@ async def test_restore(ops_test: OpsTest, add_writes_to_db) -> None:
@pytest.mark.parametrize("cloud_provider", ["AWS", "GCP"])
async def test_restore_new_cluster(ops_test: OpsTest, add_writes_to_db, cloud_provider):
# configure test for the cloud provider
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)
await helpers.set_credentials(ops_test, cloud=cloud_provider)
if cloud_provider == "AWS":
configuration_parameters = {
Expand Down Expand Up @@ -383,7 +391,7 @@ async def test_restore_new_cluster(ops_test: OpsTest, add_writes_to_db, cloud_pr
@pytest.mark.abort_on_fail
async def test_update_backup_password(ops_test: OpsTest) -> None:
"""Verifies that after changing the backup password the pbm tool is updated and functional."""
db_app_name = await helpers.app_name(ops_test)
db_app_name = await get_app_name(ops_test)
db_unit = await helpers.get_leader_unit(ops_test)

# wait for charm to be idle before setting password
Expand Down
Loading