test_validate.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import io
  2. import string
  3. import sys
  4. import os
  5. from flexmock import flexmock
  6. import pytest
  7. from borgmatic.config import validate as module
  8. def test_schema_filename_returns_plausable_path():
  9. schema_path = module.schema_filename()
  10. assert schema_path.endswith('/schema.yaml')
  11. def mock_config_and_schema(config_yaml):
  12. '''
  13. Set up mocks for the config config YAML string and the default schema so that pykwalify consumes
  14. them when parsing the configuration. This is a little brittle in that it's relying on the code
  15. under test to open() the respective files in a particular order.
  16. '''
  17. schema_stream = open(module.schema_filename())
  18. config_stream = io.StringIO(config_yaml)
  19. builtins = flexmock(sys.modules['builtins']).should_call('open').mock
  20. builtins.should_receive('open').and_return(schema_stream).and_return(config_stream)
  21. flexmock(os.path).should_receive('exists').and_return(True)
  22. def test_parse_configuration_transforms_file_into_mapping():
  23. mock_config_and_schema(
  24. '''
  25. location:
  26. source_directories:
  27. - /home
  28. - /etc
  29. repository: hostname.borg
  30. retention:
  31. keep_daily: 7
  32. consistency:
  33. checks:
  34. - repository
  35. - archives
  36. '''
  37. )
  38. result = module.parse_configuration('config.yaml', 'schema.yaml')
  39. assert result == {
  40. 'location': {'source_directories': ['/home', '/etc'], 'repository': 'hostname.borg'},
  41. 'retention': {'keep_daily': 7},
  42. 'consistency': {'checks': ['repository', 'archives']},
  43. }
  44. def test_parse_configuration_passes_through_quoted_punctuation():
  45. escaped_punctuation = string.punctuation.replace('\\', r'\\').replace('"', r'\"')
  46. mock_config_and_schema(
  47. '''
  48. location:
  49. source_directories:
  50. - /home
  51. repository: "{}.borg"
  52. '''.format(escaped_punctuation)
  53. )
  54. result = module.parse_configuration('config.yaml', 'schema.yaml')
  55. assert result == {
  56. 'location': {
  57. 'source_directories': ['/home'],
  58. 'repository': '{}.borg'.format(string.punctuation),
  59. },
  60. }
  61. def test_parse_configuration_raises_for_missing_config_file():
  62. with pytest.raises(FileNotFoundError):
  63. module.parse_configuration('config.yaml', 'schema.yaml')
  64. def test_parse_configuration_raises_for_missing_schema_file():
  65. mock_config_and_schema('')
  66. builtins = flexmock(sys.modules['builtins'])
  67. builtins.should_receive('open').with_args('schema.yaml').and_raise(FileNotFoundError)
  68. with pytest.raises(FileNotFoundError):
  69. module.parse_configuration('config.yaml', 'schema.yaml')
  70. def test_parse_configuration_raises_for_syntax_error():
  71. mock_config_and_schema('invalid = yaml')
  72. with pytest.raises(module.Validation_error):
  73. module.parse_configuration('config.yaml', 'schema.yaml')
  74. def test_parse_configuration_raises_for_validation_error():
  75. mock_config_and_schema(
  76. '''
  77. location:
  78. source_directories: yes
  79. repository: hostname.borg
  80. '''
  81. )
  82. with pytest.raises(module.Validation_error):
  83. module.parse_configuration('config.yaml', 'schema.yaml')