From a8f561872f52ed4b37c258423541d7fd5394c3dd Mon Sep 17 00:00:00 2001 From: Carmen Alvarez Date: Sun, 15 Dec 2024 00:33:42 +0100 Subject: [PATCH 1/2] Provide an alternate app config yaml file for tests. --- slackhealthbot/settings.py | 6 ++++- tests/testsupport/config/app-test.yaml | 32 ++++++++++++++++++++++++++ tests/testsupport/fixtures/app.py | 7 ++++-- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 tests/testsupport/config/app-test.yaml diff --git a/slackhealthbot/settings.py b/slackhealthbot/settings.py index 7a5507f3..81994a76 100644 --- a/slackhealthbot/settings.py +++ b/slackhealthbot/settings.py @@ -1,5 +1,6 @@ import dataclasses import datetime as dt +import os from pathlib import Path import yaml @@ -93,7 +94,10 @@ def _load_yaml_file( @classmethod def _load_merged_config(cls) -> dict: default_config = cls._load_yaml_file("config/app-default.yaml", required=True) - custom_config = cls._load_yaml_file("config/app-custom.yaml", required=False) + custom_config = cls._load_yaml_file( + os.environ.get("SHB_CUSTOM_CONFIG_PATH", "config/app-custom.yaml"), + required=False, + ) return deep_update(default_config, custom_config) @classmethod diff --git a/tests/testsupport/config/app-test.yaml b/tests/testsupport/config/app-test.yaml new file mode 100644 index 00000000..c48c50fc --- /dev/null +++ b/tests/testsupport/config/app-test.yaml @@ -0,0 +1,32 @@ +# App config for test scenarios + +logging: + sql_log_level: "DEBUG" + +fitbit: + activities: + activity_types: + - name: Dancing + id: 123 + report_daily: true + report_realtime: true + + - name: Treadmill + id: 90019 + report_daily: true + report_realtime: false + + - name: Spinning + id: 55001 + report_daily: false + report_realtime: true + + - name: Walking + id: 55001 + report_daily: false + report_realtime: true + + - name: Walk + id: 90013 + report_daily: false + report_realtime: true diff --git a/tests/testsupport/fixtures/app.py b/tests/testsupport/fixtures/app.py index 9d5aa588..2bfd44ee 100644 --- a/tests/testsupport/fixtures/app.py +++ b/tests/testsupport/fixtures/app.py @@ -12,6 +12,9 @@ def client(mocked_async_session) -> TestClient: return TestClient(app) -@pytest.fixture -def settings() -> Settings: +@pytest.fixture(autouse=True) +def settings(monkeypatch: pytest.MonkeyPatch) -> Settings: + monkeypatch.setenv( + "SHB_CUSTOM_CONFIG_PATH", "tests/testsupport/config/app-test.yaml" + ) return app.container.settings.provided() From 63dc3715800109ba2e8074c098c99ed41b9164d4 Mon Sep 17 00:00:00 2001 From: Carmen Alvarez Date: Sun, 15 Dec 2024 14:39:26 +0100 Subject: [PATCH 2/2] Prevent concurrency issues regarding settings file parsing in parallel tests. Write the merged settings file to a unique temporary file. Reset the singletons after each test. --- slackhealthbot/settings.py | 11 +++++++---- tests/testsupport/fixtures/app.py | 7 +++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/slackhealthbot/settings.py b/slackhealthbot/settings.py index 81994a76..2a80a86f 100644 --- a/slackhealthbot/settings.py +++ b/slackhealthbot/settings.py @@ -2,6 +2,7 @@ import datetime as dt import os from pathlib import Path +from tempfile import NamedTemporaryFile import yaml from pydantic import AnyHttpUrl, BaseModel, HttpUrl @@ -74,7 +75,6 @@ class AppSettings(BaseSettings): fitbit: Fitbit model_config = SettingsConfigDict( env_nested_delimiter="__", - yaml_file="config/app-merged.yaml", ) @classmethod @@ -109,9 +109,12 @@ def settings_customise_sources( **kwargs, ) -> tuple[PydanticBaseSettingsSource, ...]: merged_config = cls._load_merged_config() - with open("config/app-merged.yaml", "w", encoding="utf-8") as file: - yaml.safe_dump(merged_config, file) - yaml_settings_source = YamlConfigSettingsSource(settings_cls) + with NamedTemporaryFile(mode="w") as file: + yaml.safe_dump(merged_config, file.file) + yaml_settings_source = YamlConfigSettingsSource( + settings_cls, + yaml_file=file.name, + ) return (env_settings, yaml_settings_source) @property diff --git a/tests/testsupport/fixtures/app.py b/tests/testsupport/fixtures/app.py index 2bfd44ee..f2071fd7 100644 --- a/tests/testsupport/fixtures/app.py +++ b/tests/testsupport/fixtures/app.py @@ -18,3 +18,10 @@ def settings(monkeypatch: pytest.MonkeyPatch) -> Settings: "SHB_CUSTOM_CONFIG_PATH", "tests/testsupport/config/app-test.yaml" ) return app.container.settings.provided() + + +@pytest.fixture(autouse=True) +def reset_container(): + # Reset singletons for each test. + # https://github.com/ets-labs/python-dependency-injector/issues/421 + app.container.reset_singletons()