def test_env(): """Setup environment for main() tests.""" settings = Settings( prometheus_pushgateway_url="https://prom.example.com/push", acoustic_client_id="CLIENT_ID", acoustic_client_secret="CLIENT_SECRET", # pragma: allowlist secret acoustic_refresh_token="REFRESH_TOKEN", acoustic_main_table_id=1234, acoustic_newsletter_table_id=12345, acoustic_product_subscriptions_id=123456, acoustic_retry_limit=6, acoustic_batch_limit=20, acoustic_server_number=6, acoustic_loop_min_secs=5, acoustic_max_backlog=None, acoustic_max_retry_backlog=None, acoustic_sync_feature_flag=True, acoustic_integration_feature_flag=True, ) patcher_sleep = mock.patch("ctms.bin.acoustic_sync.sleep", side_effect=[None, HaltLoop]) patcher_push = mock.patch("ctms.background_metrics.push_to_gateway") mock_sleep = patcher_sleep.start() mock_push = patcher_push.start() try: yield { "settings": settings, "mock_sleep": mock_sleep, "mock_push": mock_push, } finally: patcher_sleep.stop() patcher_push.stop()
def test_settings(): """Set settings for heartbeat tests.""" settings = { "acoustic_retry_limit": 5, "acoustic_batch_limit": 25, "acoustic_loop_min_secs": 10, } app.dependency_overrides[get_settings] = lambda: Settings(**settings) yield settings del app.dependency_overrides[get_settings]
def test_main_recent_update(tmp_path): """healthcheck_sync succeeds on recent update.""" health_path = tmp_path / "healthcheck" update_healthcheck(health_path) settings = Settings( background_healthcheck_path=str(health_path), background_healthcheck_age_s=30, ) with capture_logs() as caplogs: exit_code = main(settings) assert exit_code == 0 assert len(caplogs) == 1 log = caplogs[0] assert log["event"] == "Healthcheck passed" assert log["age"] < 0.1
def test_main_old_update(tmp_path): """healthcheck_sync fails on old update.""" health_path = tmp_path / "healthcheck" old_date = datetime.now(tz=timezone.utc) - timedelta(seconds=120) old_date_iso = old_date.isoformat() with open(health_path, "w", encoding="utf8") as health_file: health_file.write(old_date_iso) settings = Settings( background_healthcheck_path=str(health_file), background_healthcheck_age_s=30, ) with capture_logs() as caplogs: exit_code = main(settings) assert exit_code == 1 assert len(caplogs) == 1 log = caplogs[0] assert log == { "event": "Healthcheck failed", "exc_info": True, "log_level": "error", }
def engine(pytestconfig): """Return a SQLAlchemy engine for a fresh test database.""" orig_db_url = Settings().db_url if orig_db_url.path.endswith("test"): # The database ends with test, assume the caller wanted us to use it test_db_url = orig_db_url drop_db = False assert database_exists(test_db_url) else: # Assume the regular database was passed, create a new test database test_db_url = PostgresDsn.build( scheme=orig_db_url.scheme, user=orig_db_url.user, password=orig_db_url.password, host=orig_db_url.host, port=orig_db_url.port, path=orig_db_url.path + "_test", query=orig_db_url.query, fragment=orig_db_url.fragment, ) drop_db = True # (Re)create the test database test_db_exists = database_exists(test_db_url) if test_db_exists: drop_database(test_db_url) create_database(test_db_url) echo = pytestconfig.getoption("verbose") > 2 test_engine = create_engine(test_db_url, echo=echo) # TODO: Convert to running alembic migrations Base.metadata.create_all(bind=test_engine) yield test_engine test_engine.dispose() if drop_db: drop_database(test_db_url)
from logging.config import fileConfig from alembic import context from sqlalchemy import engine_from_config, pool from ctms.config import Settings from ctms.database import get_db_engine from ctms.models import Base settings = Settings() # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config # Interpret the config file for Python logging. # This line sets up loggers basically. fileConfig(config.config_file_name) # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata target_metadata = Base.metadata # other values from the config, defined by the needs of env.py, # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc.
def settings(): return Settings()