-
Notifications
You must be signed in to change notification settings - Fork 424
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: wait for dependent services before running tests (#11780)
- Loading branch information
1 parent
315a48f
commit e9dbe4f
Showing
8 changed files
with
145 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# | ||
# This file is autogenerated by pip-compile with Python 3.9 | ||
# by the following command: | ||
# | ||
# pip-compile --allow-unsafe --no-annotate .riot/requirements/151d7b0.in | ||
# | ||
amqp==2.6.1 | ||
attrs==24.3.0 | ||
cassandra-driver==3.29.2 | ||
certifi==2024.12.14 | ||
charset-normalizer==3.4.0 | ||
click==8.1.7 | ||
coverage[toml]==7.6.9 | ||
exceptiongroup==1.2.2 | ||
future==1.0.0 | ||
geomet==0.2.1.post1 | ||
hypothesis==6.45.0 | ||
idna==3.10 | ||
importlib-metadata==8.5.0 | ||
iniconfig==2.0.0 | ||
kombu==4.2.2.post1 | ||
mock==5.1.0 | ||
mysql-connector-python==9.1.0 | ||
opentracing==2.4.0 | ||
packaging==24.2 | ||
pluggy==1.5.0 | ||
psycopg2-binary==2.9.10 | ||
pytest==8.3.4 | ||
pytest-cov==6.0.0 | ||
pytest-mock==3.14.0 | ||
pytest-randomly==3.16.0 | ||
python-dateutil==2.9.0.post0 | ||
pytz==2024.2 | ||
requests==2.32.3 | ||
six==1.17.0 | ||
sortedcontainers==2.4.0 | ||
tomli==2.2.1 | ||
urllib3==2.2.3 | ||
vertica-python==0.6.14 | ||
vine==1.3.0 | ||
zipp==3.21.0 |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,153 @@ | ||
import logging | ||
import os | ||
import sys | ||
import time | ||
import typing as t | ||
|
||
from cassandra.cluster import Cluster | ||
from cassandra.cluster import NoHostAvailable | ||
from contrib.config import CASSANDRA_CONFIG | ||
from contrib.config import ELASTICSEARCH_CONFIG | ||
from contrib.config import HTTPBIN_CONFIG | ||
from contrib.config import MYSQL_CONFIG | ||
from contrib.config import OPENSEARCH_CONFIG | ||
from contrib.config import POSTGRES_CONFIG | ||
from contrib.config import RABBITMQ_CONFIG | ||
from contrib.config import VERTICA_CONFIG | ||
import kombu | ||
import mysql.connector | ||
from psycopg2 import OperationalError | ||
from psycopg2 import connect | ||
import requests | ||
import vertica_python | ||
|
||
|
||
def try_until_timeout(exception): | ||
logging.basicConfig(level=logging.INFO) | ||
log = logging.getLogger(__name__) | ||
|
||
|
||
def try_until_timeout(exception, tries: int = 100, timeout: float = 0.2, args: t.Optional[t.Dict[str, t.Any]] = None): | ||
"""Utility decorator that tries to call a check until there is a | ||
timeout. The default timeout is about 20 seconds. | ||
""" | ||
if not args: | ||
args = {} | ||
|
||
def wrap(fn): | ||
def wrapper(*args, **kwargs): | ||
def wrapper(**kwargs): | ||
err = None | ||
|
||
for _ in range(100): | ||
_kwargs = args.copy() | ||
_kwargs.update(kwargs) | ||
|
||
for i in range(tries): | ||
try: | ||
fn() | ||
log.info("Attempt %d: %s(%r)", i, fn.__name__, _kwargs) | ||
fn(**_kwargs) | ||
except exception as e: | ||
err = e | ||
time.sleep(0.2) | ||
time.sleep(timeout) | ||
else: | ||
break | ||
else: | ||
if err: | ||
raise err | ||
log.info("Succeeded: %s", fn.__name__) | ||
|
||
return wrapper | ||
|
||
return wrap | ||
|
||
|
||
@try_until_timeout(OperationalError) | ||
def check_postgres(): | ||
conn = connect(**POSTGRES_CONFIG) | ||
@try_until_timeout(OperationalError, args={"pg_config": POSTGRES_CONFIG}) | ||
def check_postgres(pg_config): | ||
conn = connect(**pg_config) | ||
try: | ||
conn.cursor().execute("SELECT 1;") | ||
finally: | ||
conn.close() | ||
|
||
|
||
@try_until_timeout(NoHostAvailable) | ||
def check_cassandra(): | ||
with Cluster(**CASSANDRA_CONFIG).connect() as conn: | ||
@try_until_timeout(NoHostAvailable, args={"cassandra_config": CASSANDRA_CONFIG}) | ||
def check_cassandra(cassandra_config): | ||
with Cluster(**cassandra_config).connect() as conn: | ||
conn.execute("SELECT now() FROM system.local") | ||
|
||
|
||
@try_until_timeout(Exception) | ||
def check_mysql(): | ||
conn = mysql.connector.connect(**MYSQL_CONFIG) | ||
@try_until_timeout(Exception, args={"mysql_config": MYSQL_CONFIG}) | ||
def check_mysql(mysql_config): | ||
conn = mysql.connector.connect(**mysql_config) | ||
try: | ||
conn.cursor().execute("SELECT 1;") | ||
finally: | ||
conn.close() | ||
|
||
|
||
@try_until_timeout(Exception) | ||
def check_vertica(): | ||
conn = vertica_python.connect(**VERTICA_CONFIG) | ||
@try_until_timeout(Exception, args={"vertica_config": VERTICA_CONFIG}) | ||
def check_vertica(vertica_config): | ||
conn = vertica_python.connect(**vertica_config) | ||
try: | ||
conn.cursor().execute("SELECT 1;") | ||
finally: | ||
conn.close() | ||
|
||
|
||
@try_until_timeout(Exception) | ||
def check_rabbitmq(): | ||
url = "amqp://{user}:{password}@{host}:{port}//".format(**RABBITMQ_CONFIG) | ||
@try_until_timeout(Exception, args={"url": "amqp://{user}:{password}@{host}:{port}//".format(**RABBITMQ_CONFIG)}) | ||
def check_rabbitmq(url): | ||
conn = kombu.Connection(url) | ||
try: | ||
conn.connect() | ||
finally: | ||
conn.release() | ||
|
||
|
||
@try_until_timeout(Exception, args={"url": os.environ.get("DD_TRACE_AGENT_URL", "http://localhost:8126")}) | ||
def check_agent(url): | ||
if not url.endswith("/"): | ||
url += "/" | ||
|
||
res = requests.get(url) | ||
if res.status_code not in (404, 200): | ||
raise Exception("Agent not ready") | ||
|
||
|
||
@try_until_timeout(Exception, args={"url": "http://{host}:{port}/".format(**ELASTICSEARCH_CONFIG)}) | ||
def check_elasticsearch(url): | ||
requests.get(url).raise_for_status() | ||
|
||
|
||
@try_until_timeout( | ||
Exception, tries=120, timeout=1, args={"url": "http://{host}:{port}/".format(**OPENSEARCH_CONFIG)} | ||
) # 2 minutes, OpenSearch is slow to start | ||
def check_opensearch(url): | ||
requests.get(url).raise_for_status() | ||
|
||
|
||
@try_until_timeout(Exception, args={"url": "http://{host}:{port}/".format(**HTTPBIN_CONFIG)}) | ||
def check_httpbin(url): | ||
requests.get(url).raise_for_status() | ||
|
||
|
||
if __name__ == "__main__": | ||
check_functions = { | ||
"cassandra": check_cassandra, | ||
"postgres": check_postgres, | ||
"ddagent": check_agent, | ||
"elasticsearch": check_elasticsearch, | ||
"httpbin_local": check_httpbin, | ||
"mysql": check_mysql, | ||
"vertica": check_vertica, | ||
"opensearch": check_opensearch, | ||
"postgres": check_postgres, | ||
"rabbitmq": check_rabbitmq, | ||
"testagent": check_agent, | ||
"vertica": check_vertica, | ||
} | ||
if len(sys.argv) >= 2: | ||
for service in sys.argv[1:]: | ||
check_functions[service]() | ||
if service not in check_functions: | ||
log.warning("Unknown service: %s", service) | ||
else: | ||
check_functions[service]() | ||
else: | ||
print("usage: python {} SERVICE_NAME".format(sys.argv[0])) | ||
sys.exit(1) |