Skip to content

Commit

Permalink
Attempts/steps to try to stabilize exporter tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shayancanonical committed Jun 28, 2024
1 parent 7c24a35 commit 4ac2cb7
Show file tree
Hide file tree
Showing 2 changed files with 265 additions and 157 deletions.
176 changes: 19 additions & 157 deletions tests/integration/test_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@
import logging

import pytest
import requests
import tenacity
import urllib3
from pytest_operator.plugin import OpsTest

from . import juju_
from .helpers import (
APPLICATION_DEFAULT_APP_NAME,
MYSQL_DEFAULT_APP_NAME,
MYSQL_ROUTER_DEFAULT_APP_NAME,
get_tls_certificate_issuer,
)

logger = logging.getLogger(__name__)
Expand All @@ -25,22 +23,14 @@
APPLICATION_APP_NAME = APPLICATION_DEFAULT_APP_NAME
GRAFANA_AGENT_APP_NAME = "grafana-agent"
SLOW_TIMEOUT = 25 * 60
RETRY_TIMEOUT = 3 * 60

if juju_.is_3_or_higher:
TLS_APP_NAME = "self-signed-certificates"
TLS_CONFIG = {"ca-common-name": "Test CA"}
else:
TLS_APP_NAME = "tls-certificates-operator"
TLS_CONFIG = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
# TODO: reduce to < 5 * 60, after https://github.com/rluisr/mysqlrouter_exporter/issues/67 is resolved
RETRY_TIMEOUT = 7 * 60


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
async def test_exporter_endpoint(ops_test: OpsTest, mysql_router_charm_series: str) -> None:
"""Test that exporter endpoint is functional."""
http = urllib3.PoolManager()

# Build and deploy applications
mysqlrouter_charm = await ops_test.build_charm(".")

Expand Down Expand Up @@ -129,17 +119,13 @@ async def test_exporter_endpoint(ops_test: OpsTest, mysql_router_charm_series: s
unit_address = await unit.get_public_address()

try:
http.request("GET", f"http://{unit_address}:49152/metrics")
except urllib3.exceptions.MaxRetryError as e:
assert (
"[Errno 111] Connection refused" in e.reason.args[0]
), "❌ expected connection refused error"
with requests.Session() as session:
session.get(f"http://{unit_address}:49152/metrics", stream=False)
except requests.exceptions.ConnectionError as e:
assert "[Errno 111] Connection refused" in str(e), "❌ expected connection refused error"
else:
assert False, "❌ can connect to metrics endpoint without relation with cos"

# clear connection pool before relating cos-agent which starts mysql_router_exporter
http.clear()

logger.info("Relating mysqlrouter with grafana agent")
await ops_test.model.relate(
f"{GRAFANA_AGENT_APP_NAME}:cos-agent", f"{MYSQL_ROUTER_APP_NAME}:cos-agent"
Expand All @@ -151,117 +137,14 @@ async def test_exporter_endpoint(ops_test: OpsTest, mysql_router_charm_series: s
wait=tenacity.wait_fixed(10),
):
with attempt:
jmx_resp = http.request("GET", f"http://{unit_address}:49152/metrics")
assert (
jmx_resp.status == 200
), "❌ cannot connect to metrics endpoint with relation with cos"
assert "mysqlrouter_route_health" in str(
jmx_resp.data
), "❌ did not find expected metric in response"

logger.info("Removing relation between mysqlrouter and grafana agent")
await mysql_router_app.remove_relation(
f"{GRAFANA_AGENT_APP_NAME}:cos-agent", f"{MYSQL_ROUTER_APP_NAME}:cos-agent"
)

for attempt in tenacity.Retrying(
reraise=True,
stop=tenacity.stop_after_delay(RETRY_TIMEOUT),
wait=tenacity.wait_fixed(10),
):
with attempt:
try:
http.request("GET", f"http://{unit_address}:49152/metrics")
except urllib3.exceptions.MaxRetryError as e:
with requests.Session() as session:
response = session.get(f"http://{unit_address}:49152/metrics", stream=False)
assert (
"[Errno 111] Connection refused" in e.reason.args[0]
), "❌ expected connection refused error"
else:
assert False, "❌ can connect to metrics endpoint without relation with cos"

http.clear()


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
async def test_exporter_endpoint_with_tls(ops_test: OpsTest) -> None:
"""Test that the exporter endpoint works when related with TLS"""
http = urllib3.PoolManager()

mysql_router_app = ops_test.model.applications[MYSQL_ROUTER_APP_NAME]
mysql_router_unit = mysql_router_app.units[0]

issuer = await get_tls_certificate_issuer(
ops_test,
mysql_router_unit.name,
socket="/var/snap/charmed-mysql/common/run/mysqlrouter/mysql.sock",
)
assert (
"Issuer: CN = MySQL_Router_Auto_Generated_CA_Certificate" in issuer
), "Expected mysqlrouter autogenerated certificate"

logger.info(f"Deploying {TLS_APP_NAME}")
await ops_test.model.deploy(
TLS_APP_NAME,
application_name=TLS_APP_NAME,
channel="stable",
config=TLS_CONFIG,
series="jammy",
)
await ops_test.model.wait_for_idle([TLS_APP_NAME], status="active", timeout=SLOW_TIMEOUT)

logger.info(f"Relating mysqlrouter with {TLS_APP_NAME}")

await ops_test.model.relate(
f"{MYSQL_ROUTER_APP_NAME}:certificates", f"{TLS_APP_NAME}:certificates"
)

mysql_test_app = ops_test.model.applications[APPLICATION_APP_NAME]
unit_address = await mysql_test_app.units[0].get_public_address()

for attempt in tenacity.Retrying(
reraise=True,
stop=tenacity.stop_after_delay(RETRY_TIMEOUT),
wait=tenacity.wait_fixed(10),
):
with attempt:
try:
http.request("GET", f"http://{unit_address}:49152/metrics")
except urllib3.exceptions.MaxRetryError as e:
assert (
"[Errno 111] Connection refused" in e.reason.args[0]
), "❌ expected connection refused error"
else:
assert False, "❌ can connect to metrics endpoint without relation with cos"

# clear connection pool before relating cos-agent which starts mysql_router_exporter
http.clear()

logger.info("Relating mysqlrouter with grafana agent")
await ops_test.model.relate(
f"{GRAFANA_AGENT_APP_NAME}:cos-agent", f"{MYSQL_ROUTER_APP_NAME}:cos-agent"
)

for attempt in tenacity.Retrying(
reraise=True,
stop=tenacity.stop_after_delay(RETRY_TIMEOUT),
wait=tenacity.wait_fixed(10),
):
with attempt:
jmx_resp = http.request("GET", f"http://{unit_address}:49152/metrics")
assert (
jmx_resp.status == 200
), "❌ cannot connect to metrics endpoint with relation with cos"
assert "mysqlrouter_route_health" in str(
jmx_resp.data
), "❌ did not find expected metric in response"

issuer = await get_tls_certificate_issuer(
ops_test,
mysql_router_unit.name,
socket="/var/snap/charmed-mysql/common/run/mysqlrouter/mysql.sock",
)
assert "CN = Test CA" in issuer, f"Expected mysqlrouter certificate from {TLS_APP_NAME}"
response.status_code == 200
), "❌ cannot connect to metrics endpoint with relation with cos"
assert "mysqlrouter_route_health" in str(
response.text
), "❌ did not find expected metric in response"

logger.info("Removing relation between mysqlrouter and grafana agent")
await mysql_router_app.remove_relation(
Expand All @@ -275,32 +158,11 @@ async def test_exporter_endpoint_with_tls(ops_test: OpsTest) -> None:
):
with attempt:
try:
http.request("GET", f"http://{unit_address}:49152/metrics")
except urllib3.exceptions.MaxRetryError as e:
assert (
"[Errno 111] Connection refused" in e.reason.args[0]
with requests.Session() as session:
session.get(f"http://{unit_address}:49152/metrics", stream=False)
except requests.exceptions.ConnectionError as e:
assert "[Errno 111] Connection refused" in str(
e
), "❌ expected connection refused error"
else:
assert False, "❌ can connect to metrics endpoint without relation with cos"

logger.info(f"Removing relation between mysqlrouter and {TLS_APP_NAME}")
await mysql_router_app.remove_relation(
f"{MYSQL_ROUTER_APP_NAME}:certificates", f"{TLS_APP_NAME}:certificates"
)

for attempt in tenacity.Retrying(
reraise=True,
stop=tenacity.stop_after_delay(RETRY_TIMEOUT),
wait=tenacity.wait_fixed(10),
):
with attempt:
issuer = await get_tls_certificate_issuer(
ops_test,
mysql_router_unit.name,
socket="/var/snap/charmed-mysql/common/run/mysqlrouter/mysql.sock",
)
assert (
"Issuer: CN = MySQL_Router_Auto_Generated_CA_Certificate" in issuer
), "Expected mysqlrouter autogenerated certificate"

http.clear()
Loading

0 comments on commit 4ac2cb7

Please sign in to comment.