def test_missing_required_overlay_file( config_default_builder: ConfigBuilder) -> None: """Provides an explicit TOML source that doesn't exists - should raise an exception.""" from valiant.config.source import TomlSource # The exception should only occur when build() is called config_default_builder.add_source( TomlSource(Path("/i/do/not/exist.toml"), optional=False)) with pytest.raises(ValueError): config_default_builder.build()
def test_empty_builder() -> None: """Test that a builder with no sources returns None at build time.""" from valiant.config import ConfigBuilder builder = ConfigBuilder() c = builder.build() # Nothing was processed so we get None assert not c
def test_basic_build_with_two_mapping_sources_with_object() -> None: """Check that a second source overlays a value.""" from valiant.config import ConfigBuilder from valiant.config.source import MappingSource builder = ConfigBuilder() builder.add_source( MappingSource({ "name": "Fred", "pets": { "fido": "dog", "mittens": "cat" } })) builder.add_source( MappingSource({ "name": "Jane", "pets": { "flipper": "fish" } })) builder.add_source(MappingSource({"name": "Dewi"})) c = builder.build() assert c assert c["name"] == "Dewi" assert c["pets"]["flipper"] == "fish" assert "fido" not in c["pets"] assert "mittens" not in c["pets"] # The dictionary read is recorded only once assert c["_builder_metadata"]["build_results"]["dictionary"] == "Read"
def test_basic_build_with_single_mapping_source() -> None: """Basic test that a source config is reflected in a build.""" from valiant.config import ConfigBuilder from valiant.config.source import MappingSource builder = ConfigBuilder() builder.add_source(MappingSource({"name": "Fred"})) c = builder.build() assert c assert c["name"] == "Fred" assert c["_builder_metadata"]["build_results"]["dictionary"] == "Read"
def test_no_repo_config(config_default_builder: ConfigBuilder) -> None: """Expect failure when there are no repository_configurations.""" from valiant.config.source import MappingSource config_default_builder.add_source( MappingSource({"tool": { "valiant": { "repository_configurations": {} } }})) with pytest.raises(ValueError): get_config_instance(config_default_builder)
def test_basic_build_with_two_mapping_sources() -> None: """Check that a second source overlays a value.""" from valiant.config import ConfigBuilder from valiant.config.source import MappingSource builder = ConfigBuilder() builder.add_source(MappingSource({"name": "Fred"})) builder.add_source(MappingSource({"name": "Jane"})) c = builder.build() assert c assert c["name"] == "Jane" # The dictionary read is recorded only once assert c["_builder_metadata"]["build_results"]["dictionary"] == "Read"
def test_no_default_repo( config_default_builder: ConfigBuilder) -> None: # noqa:ANN001 """Expect failure when the default_repo isn't listed in repository_configurations.""" from valiant.config.source import MappingSource config_default_builder.add_source( MappingSource( {"tool": { "valiant": { "default_repository": "random_repo" } }})) with pytest.raises(ValueError): get_config_instance(config_default_builder)
def test_basic_build_with_two_mapping_sources_that_are_filtered_out() -> None: """Test handling of a filter that throws everything away.""" from valiant.config import ConfigBuilder from valiant.config.source import MappingSource builder = ConfigBuilder(filter=lambda d: {}) assert builder builder.add_source(MappingSource({"name": "Fred"})) builder.add_source(MappingSource({"name": "Jane"})) c = builder.build() assert c assert "name" not in c assert c["_builder_metadata"]["build_results"]["dictionary"] == "Read"
def test_basic_overlay_file( tmp_path: Path, config_default_builder: ConfigBuilder, datafiles: py.path, copy_test_files: Any, ) -> None: """Manually adds a config dict with a logging_configuration_file.""" from valiant.config.source import TomlSource config_default_builder.add_source( TomlSource(Path(os.path.join(FIXTURE_DIR, "basic_logfile.toml")), optional=False)) c = get_config_instance(config_default_builder) assert c.logging_configuration_file == Path( "/tmp/valiant_test_data/logging.conf" # noqa: S108 )
def test_basic_overlay_mapping(config_default_builder: ConfigBuilder, datafiles: py.path) -> None: """Manually adds a config dict with a logging_configuration_file.""" from valiant.config.source import MappingSource config_default_builder.add_source( MappingSource({ "tool": { "valiant": { "logging_configuration_file": Path(FIXTURE_DIR, "logging.conf") } } })) c = get_config_instance(config_default_builder) assert c.logging_configuration_file == Path(FIXTURE_DIR, "logging.conf")
def create_valiant_builder( include_pyproject: bool = True, include_user_config: bool = True, include_site_config: bool = True, ) -> ConfigBuilder: """Create a config builder ready for Valiant. Args: include_pyproject: True if the local pyproject.toml file is to be read include_user_config: True if the user's config directory is to be used include_site_config: True if the system's config directory is to be used Returns: A ConfigBuilder instance readied with the expected config sources """ from valiant import Valiant vendor, app, version = Valiant.application_details() return ConfigBuilder.create_default_builder( initial_data=get_valiant_base_config(), vendor=vendor, app=app, version=version, include_pyproject=include_pyproject, include_user_config=include_user_config, include_site_config=include_site_config, filter=valiant_config_filter, )
def test_explicit_file_overlay_from_valiant_config( tmp_path: Path, config_default_builder: ConfigBuilder, pypi_repo: PyPiRepository, valiant_app_name: str, valiant_version: str, datafiles: py.path, ) -> None: """Provides an explicit TOML source to overlay the default config.""" from string import Template from valiant.config.source import TomlSource config_default_builder.add_source( TomlSource(Path(os.path.join(FIXTURE_DIR, "config_output.toml")), optional=False)) c = get_config_instance(config_default_builder) assert c.configuration_dir == Path("/tmp/valiant_test/etc") # noqa: S108 assert c.cache_dir == Path("/tmp/valiant_test/var/cache") # noqa: S108 assert c.log_dir == Path("/tmp/valiant_test/var/log") # noqa: S108 assert c.default_reports == set(["basic", "spdx", "safety"]) # Repository config assert c.default_repository == "pypi" assert c.default_repository_name == "pypi" assert c.repository_configurations == {"pypi": pypi_repo} assert c.default_repository_configuration == pypi_repo assert c.repository_names == ["pypi"] assert c.get_repository_configuration("pypi") == pypi_repo # Local plugins should be empty assert c.local_plugin_paths == [] assert c.local_report_plugins == {} # Logging assert not c.logging_configuration_file # Requests cache assert c.requests_cache["backend"] == "sqlite" assert c.requests_cache["expire_after"] == 86400 assert (Template(str(c.requests_cache["file"])).substitute( log_dir=c.log_dir, cache_dir=c.cache_dir, configuration_dir=c.configuration_dir, ) == f"{c.cache_dir}/{valiant_app_name}-{valiant_version}-requests-cache")
def test_default_builder_with_no_sources() -> None: """Expect that the default builder doesn't build anything without inputs.""" from valiant.config import ConfigBuilder builder = ConfigBuilder.create_default_builder(include_pyproject=False, include_user_config=False, include_site_config=False) assert not builder.build()
def test_explicit_file_overlay( tmp_path: Path, config_default_builder: ConfigBuilder, datafiles: py.path, ) -> None: """Provides an explicit TOML source to overlay the default config.""" from valiant.config.source import TomlSource config_default_builder.add_source( TomlSource(Path(os.path.join(FIXTURE_DIR, "basic.toml")), optional=False)) c = get_config_instance(config_default_builder) assert c.configuration_dir == Path("/tmp/valiant_test/etc") # noqa: S108 assert c.cache_dir == Path("/tmp/valiant_test/var/cache") # noqa: S108 assert c.log_dir == Path("/tmp/valiant_test/var/log") # noqa: S108 assert c.default_reports == set(["basic", "spdx"])
def get_config_instance(builder: ConfigBuilder) -> Config: """Helper function to setup a Config instance from the builder. A number of builders are provided via fixtures in conftest.py # noqa:DAR201 # noqa:DAR401 """ from valiant.config.util import ConfigMapBuilder conf_map = builder.build() if conf_map: return ConfigMapBuilder.generate_valiant_config_from_map(conf_map) else: raise ValueError("Failed to generate config instance.")