From 483bd50bdf69e8683bc7b406e69771e27175e37f Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Tue, 4 Jul 2017 18:32:37 -0700 Subject: [PATCH] Tests for YAML config code. --- .../tests/integration/config/test_yaml.py | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 borgmatic/tests/integration/config/test_yaml.py diff --git a/borgmatic/tests/integration/config/test_yaml.py b/borgmatic/tests/integration/config/test_yaml.py new file mode 100644 index 000000000..ebd33a369 --- /dev/null +++ b/borgmatic/tests/integration/config/test_yaml.py @@ -0,0 +1,113 @@ +import io +import string +import sys +import os + +from flexmock import flexmock +import pytest + +from borgmatic.config import yaml as module + + +def test_schema_filename_returns_plausable_path(): + schema_path = module.schema_filename() + + assert schema_path.endswith('/schema.yaml') + + +def mock_config_and_schema(config_yaml): + ''' + Set up mocks for the config config YAML string and the default schema so that pykwalify consumes + them when parsing the configuration. This is a little brittle in that it's relying on pykwalify + to open() the respective files in a particular order. + ''' + config_stream = io.StringIO(config_yaml) + schema_stream = open(module.schema_filename()) + builtins = flexmock(sys.modules['builtins']).should_call('open').mock + builtins.should_receive('open').and_return(config_stream).and_return(schema_stream) + flexmock(os.path).should_receive('exists').and_return(True) + + +def test_parse_configuration_transforms_file_into_mapping(): + mock_config_and_schema( + ''' + location: + source_directories: + - /home + - /etc + + repository: hostname.borg + + retention: + keep_daily: 7 + + consistency: + checks: + - repository + - archives + ''' + ) + + result = module.parse_configuration('config.yaml', 'schema.yaml') + + assert result == { + 'location': {'source_directories': ['/home', '/etc'], 'repository': 'hostname.borg'}, + 'retention': {'keep_daily': 7}, + 'consistency': {'checks': ['repository', 'archives']}, + } + + +def test_parse_configuration_passes_through_quoted_punctuation(): + escaped_punctuation = string.punctuation.replace('\\', r'\\').replace('"', r'\"') + + mock_config_and_schema( + ''' + location: + source_directories: + - /home + + repository: "{}.borg" + '''.format(escaped_punctuation) + ) + + result = module.parse_configuration('config.yaml', 'schema.yaml') + + assert result == { + 'location': { + 'source_directories': ['/home'], + 'repository': '{}.borg'.format(string.punctuation), + }, + } + + +def test_parse_configuration_raises_for_missing_config_file(): + with pytest.raises(FileNotFoundError): + module.parse_configuration('config.yaml', 'schema.yaml') + + +def test_parse_configuration_raises_for_missing_schema_file(): + mock_config_and_schema('') + flexmock(os.path).should_receive('exists').with_args('schema.yaml').and_return(False) + + with pytest.raises(FileNotFoundError): + module.parse_configuration('config.yaml', 'schema.yaml') + + +def test_parse_configuration_raises_for_syntax_error(): + mock_config_and_schema('invalid = yaml') + + with pytest.raises(module.Validation_error): + module.parse_configuration('config.yaml', 'schema.yaml') + + +def test_parse_configuration_raises_for_validation_error(): + mock_config_and_schema( + ''' + location: + source_directories: yes + repository: hostname.borg + ''' + ) + + with pytest.raises(module.Validation_error): + module.parse_configuration('config.yaml', 'schema.yaml')