diff --git a/changelog.d/458.fixed.md b/changelog.d/458.fixed.md new file mode 100644 index 00000000..e337115e --- /dev/null +++ b/changelog.d/458.fixed.md @@ -0,0 +1 @@ +Actually allow zino to run without a zino.toml file, use the defaults instead. diff --git a/src/zino/config/__init__.py b/src/zino/config/__init__.py index 7d57d0dc..59f3356b 100644 --- a/src/zino/config/__init__.py +++ b/src/zino/config/__init__.py @@ -23,11 +23,14 @@ def read_configuration(config_file_name: str, poll_file_name: Optional[str] = No pydantic.ValidationError if values in it are invalid or the specified files don't exist """ - with open(config_file_name, mode="rb") as cf: - try: - config_dict = load(cf) - except TOMLDecodeError: - raise InvalidConfigurationError + try: + with open(config_file_name, mode="rb") as cf: + try: + config_dict = load(cf) + except TOMLDecodeError: + raise InvalidConfigurationError + except FileNotFoundError: + config_dict = {} # Polldevs by command line argument will override config file entry if poll_file_name: @@ -36,6 +39,6 @@ def read_configuration(config_file_name: str, poll_file_name: Optional[str] = No else: config_dict["polling"]["file"] = poll_file_name - config = Configuration.model_validate(obj=config_dict, strict=True) + config = Configuration().model_validate(obj=config_dict, strict=True) return config diff --git a/src/zino/zino.py b/src/zino/zino.py index 6c0059d1..a755d3bc 100644 --- a/src/zino/zino.py +++ b/src/zino/zino.py @@ -79,12 +79,18 @@ def load_config(args: argparse.Namespace) -> Optional[state.Configuration]: Returns the configuration specified by the config file and None if no config file name was specified as argument and no default config file exists """ + config_file = args.config_file or DEFAULT_CONFIG_FILE try: - return read_configuration(args.config_file or DEFAULT_CONFIG_FILE, args.polldevs) + with open(config_file, mode="rb"): + pass except OSError: if args.config_file: _log.fatal(f"No config file with the name {args.config_file} found.") sys.exit(1) + else: + _log.info("No config file found, using default configuration.") + try: + return read_configuration(config_file, args.polldevs) except InvalidConfigurationError: _log.fatal(f"Configuration file with the name {args.config_file or DEFAULT_CONFIG_FILE} is invalid TOML.") sys.exit(1) diff --git a/tests/config_test.py b/tests/config_test.py index 8bf70729..88e8a193 100644 --- a/tests/config_test.py +++ b/tests/config_test.py @@ -15,9 +15,9 @@ def test_pollfile_argument_overrides_pollfile_defined_in_file(self, zino_conf, p assert config assert config.polling.file == str(polldevs_conf_with_single_router) - def test_raises_error_on_file_not_found(self, tmp_path): - with pytest.raises(FileNotFoundError): - read_configuration(tmp_path / "non-existent-config.toml") + def test_succeeds_on_file_not_found(self, tmp_path): + config = read_configuration(tmp_path / "non-existent-config.toml") + assert config, "Default config not generated" def test_raises_error_on_invalid_toml_file(self, invalid_zino_conf): with pytest.raises(InvalidConfigurationError): diff --git a/tests/zino_test.py b/tests/zino_test.py index be97c00b..2cd3448b 100644 --- a/tests/zino_test.py +++ b/tests/zino_test.py @@ -91,6 +91,12 @@ def test_when_args_specified_config_file_does_not_exist_then_load_config_should_ zino.load_config(args) +def test_when_no_config_file_specified_then_load_config_should_return_default_config(tmp_path): + args = Mock(config_file=tmp_path / "non_existent_file.toml") + config = zino.load_config(args) + assert config, "load_config did not return default config for missing config file" + + def test_when_logging_config_is_invalid_then_apply_logging_config_should_exit(): with pytest.raises(SystemExit): zino.apply_logging_config({"loggers": {"zino": {"level": "invalid"}}})