Skip to content

Commit

Permalink
Periodic probes of the reference database readiness before to run int…
Browse files Browse the repository at this point in the history
…egration tests

The change was introduced after migration to MariaDB 11.4.3 which
has a few seconds delay before it starts listening for connections.
If the integration test starts reading from the database right away then
it fails.
  • Loading branch information
iagaponenko committed Nov 15, 2024
1 parent ac5d72d commit f8bbd66
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions src/admin/python/lsst/qserv/admin/cli/_integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,35 +62,36 @@ def wait_for_replication_system(repl_ctrl_uri: str) -> None:
ReplicationInterface(repl_ctrl_uri).version()


class CzarNotReady(RuntimeError):
class DbServiceNotReady(RuntimeError):
pass


@backoff.on_exception(
exception=(CzarNotReady, mysql.connector.errors.DatabaseError, MySQLInterfaceError),
exception=(DbServiceNotReady, mysql.connector.errors.DatabaseError, MySQLInterfaceError),
wait_gen=backoff.expo,
on_backoff=on_backoff(log=_log),
max_time=max_backoff_sec,
)
def wait_for_czar(czar_db_uri: str) -> None:
"""Wait for the czar to be ready.
def wait_for_db_service(db_uri: str, checkdb: str) -> None:
"""Wait for the database service to be ready.
Parameters
----------
czar_db_uri : str
The uri to the czar database.
db_uri : str
The uri to the database service.
checkdb : str
The name of the database to check for.
Raises
------
CzarNotReady
If the czar is not ready. This is handled by the backoff decorator until
a max wait time is exceeded, and then the excetpion will not be caught,
DbServiceNotReady
If the service is not ready. This is handled by the backoff decorator until
a max wait time is exceeded, and then the exception will not be caught,
and can be handled above or test execution can be aborted.
"""
parsed = urlparse(czar_db_uri)
parsed = urlparse(db_uri)

def get_databases() -> List[str]:
"""Get the names of the databases in the czar db."""
"""Get the names of the databases in the database service."""
with closing(
mysql.connector.connect(
user=parsed.username,
Expand All @@ -104,10 +105,9 @@ def get_databases() -> List[str]:
return [str(row[0]) for row in cursor.fetchall()]

databases = get_databases()
checkdb = "qservMeta"
if checkdb in databases:
return
raise CzarNotReady(f"{checkdb} not in existing databases: {databases}")
raise DbServiceNotReady(f"{checkdb} not in existing databases: {databases}")


def run_integration_tests(
Expand Down Expand Up @@ -175,7 +175,8 @@ def run_integration_tests(
raise RuntimeError("qserv_testdata sources are not present.")

if unload or load != False or reload or run_tests:
wait_for_czar(tests_data["czar-db-admin-uri"])
wait_for_db_service(tests_data["reference-db-admin-uri"], "mysql")
wait_for_db_service(tests_data["czar-db-admin-uri"], "qservMeta")
wait_for_replication_system(tests_data["replication-controller-uri"])

# If unload is True, and load is not specified (default is `None`, means
Expand Down Expand Up @@ -294,7 +295,8 @@ def run_integration_tests_http(
raise RuntimeError("qserv_testdata sources are not present.")

if unload or load != False or reload or run_tests:
wait_for_czar(tests_data["czar-db-admin-uri"])
wait_for_db_service(tests_data["reference-db-admin-uri"], "mysql")
wait_for_db_service(tests_data["czar-db-admin-uri"], "qservMeta")
wait_for_replication_system(tests_data["replication-controller-uri"])

# If unload is True, and load is not specified (default is `None`, means
Expand Down

0 comments on commit f8bbd66

Please sign in to comment.