diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 10dccc5e..cf6b7247 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -25,7 +25,7 @@ jobs: path: tests/api env: - REDIS_OM_URL: redis://localhost:6379 + REDIS_OM_URL: redis://localhost:6379/0 GITHUB_BASE_URL: http://localhost:4010 steps: diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 9b7c86b8..1de3b266 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -14,6 +14,11 @@ lint: commands: - name: lint run: pyright --project ${workspace} --outputjson ${target} + ignore: + - linters: + - pyright + paths: + - tests enabled: - black@22.3.0 - isort@5.9.3 diff --git a/runner_manager/models/settings.py b/runner_manager/models/settings.py index f942a7f5..435ad422 100644 --- a/runner_manager/models/settings.py +++ b/runner_manager/models/settings.py @@ -5,28 +5,29 @@ from pydantic import AnyHttpUrl, BaseSettings, RedisDsn +class ConfigFile(BaseSettings): + config_file: Optional[Path] = None + + def yaml_config_settings_source(settings: BaseSettings) -> Dict[str, Any]: """ A simple settings source that loads variables from a yaml file """ - config_file: Optional[Path] = settings.__config__.config.config_file - if config_file: - return yaml.full_load(config_file.read_text()) - return {} - -class ConfigFile(BaseSettings): - config_file: Optional[Path] = None + config = ConfigFile() + if config.config_file is not None: + return yaml.full_load(config.config_file.read_text()) + return {} class Settings(BaseSettings): - name: str = "runner-manager" + name: Optional[str] = "runner-manager" redis_om_url: Optional[RedisDsn] = None github_base_url: Optional[AnyHttpUrl] = None class Config: - config: ConfigFile = ConfigFile() + smart_union = True env_file = ".env" env_file_encoding = "utf-8" diff --git a/tests/unit/models/test_settings.py b/tests/unit/models/test_settings.py new file mode 100644 index 00000000..94f49a03 --- /dev/null +++ b/tests/unit/models/test_settings.py @@ -0,0 +1,72 @@ +import os +import tempfile + +import pytest +import yaml +from pytest import fixture + +from runner_manager.dependencies import get_settings +from runner_manager.models.settings import ConfigFile, Settings + + +@fixture +def yaml_data(): + return { + "name": "test-runner-manager", + "redis_om_url": "redis://localhost:6379/0", + "github_base_url": "https://github.com", + } + + +@fixture(scope="function") +def config_file(yaml_data): + # create a yaml file with some data + with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: + yaml.dump(yaml_data, f) + os.environ["CONFIG_FILE"] = f.name + config = ConfigFile() + return config.config_file + + +def test_settings_default_values(): + settings = Settings() + assert settings.name == "runner-manager" + assert settings.redis_om_url == os.getenv("REDIS_OM_URL") + assert settings.github_base_url == os.getenv("GITHUB_BASE_URL") + + +def test_invalid_redis_url(): + with pytest.raises(ValueError): + Settings(redis_om_url="invalid_redis_url") + + +def test_invalid_github_url(): + with pytest.raises(ValueError): + Settings(github_base_url="invalid_github_url") + + +def test_yaml_config(config_file, yaml_data): + settings = Settings() + assert settings.name == yaml_data["name"] + assert settings.redis_om_url == yaml_data["redis_om_url"] + assert settings.github_base_url == yaml_data["github_base_url"] + + +def test_env_file(): + os.environ["REDIS_OM_URL"] = "redis://localhost:6379/0" + os.environ["GITHUB_BASE_URL"] = "https://github.com" + os.environ["NAME"] = "test-runner-manager" + settings = Settings() + assert settings.name == os.getenv("NAME") + assert settings.redis_om_url == os.getenv("REDIS_OM_URL") + assert settings.github_base_url == os.getenv("GITHUB_BASE_URL") + + +def test_get_settings(config_file): + get_settings() + # delete config_file + os.remove(config_file) + # call settings again to ensure the cached settings are returned + get_settings() + with pytest.raises(FileNotFoundError): + Settings()