2017-07-10 19:37:11 +02:00
|
|
|
import os
|
2017-07-09 20:41:55 +02:00
|
|
|
import sys
|
2019-05-13 23:39:10 +02:00
|
|
|
from io import StringIO
|
2017-07-09 20:41:55 +02:00
|
|
|
|
2017-07-10 19:37:11 +02:00
|
|
|
import pytest
|
2019-05-13 23:39:10 +02:00
|
|
|
from flexmock import flexmock
|
2017-07-09 20:41:55 +02:00
|
|
|
|
|
|
|
from borgmatic.config import generate as module
|
|
|
|
|
|
|
|
|
|
|
|
def test_insert_newline_before_comment_does_not_raise():
|
|
|
|
field_name = 'foo'
|
|
|
|
config = module.yaml.comments.CommentedMap([(field_name, 33)])
|
2018-09-30 07:45:00 +02:00
|
|
|
config.yaml_set_comment_before_after_key(key=field_name, before='Comment')
|
2017-07-09 20:41:55 +02:00
|
|
|
|
|
|
|
module._insert_newline_before_comment(config, field_name)
|
|
|
|
|
|
|
|
|
2018-09-30 00:03:11 +02:00
|
|
|
def test_comment_out_line_skips_blank_line():
|
|
|
|
line = ' \n'
|
|
|
|
|
|
|
|
assert module._comment_out_line(line) == line
|
|
|
|
|
|
|
|
|
|
|
|
def test_comment_out_line_skips_already_commented_out_line():
|
|
|
|
line = ' # foo'
|
|
|
|
|
|
|
|
assert module._comment_out_line(line) == line
|
|
|
|
|
|
|
|
|
|
|
|
def test_comment_out_line_comments_section_name():
|
|
|
|
line = 'figgy-pudding:'
|
|
|
|
|
2019-09-18 02:00:58 +02:00
|
|
|
assert module._comment_out_line(line) == '# ' + line
|
2018-09-30 00:03:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_comment_out_line_comments_indented_option():
|
|
|
|
line = ' enabled: true'
|
|
|
|
|
2019-09-18 02:00:58 +02:00
|
|
|
assert module._comment_out_line(line) == ' # enabled: true'
|
2018-09-30 00:03:11 +02:00
|
|
|
|
|
|
|
|
2019-10-22 00:17:47 +02:00
|
|
|
def test_comment_out_line_comments_twice_indented_option():
|
|
|
|
line = ' - item'
|
|
|
|
|
|
|
|
assert module._comment_out_line(line) == ' # - item'
|
|
|
|
|
|
|
|
|
2018-09-30 00:03:11 +02:00
|
|
|
def test_comment_out_optional_configuration_comments_optional_config_only():
|
2019-11-06 18:31:00 +01:00
|
|
|
# The "# COMMENT_OUT" comment is a sentinel used to express that the following key is optional.
|
|
|
|
# It's stripped out of the final output.
|
2019-09-18 02:00:58 +02:00
|
|
|
flexmock(module)._comment_out_line = lambda line: '# ' + line
|
2018-09-30 00:03:11 +02:00
|
|
|
config = '''
|
2019-11-06 18:31:00 +01:00
|
|
|
# COMMENT_OUT
|
2018-09-30 00:03:11 +02:00
|
|
|
foo:
|
2019-11-06 18:31:00 +01:00
|
|
|
# COMMENT_OUT
|
2018-09-30 00:03:11 +02:00
|
|
|
bar:
|
|
|
|
- baz
|
|
|
|
- quux
|
|
|
|
|
|
|
|
location:
|
|
|
|
repositories:
|
|
|
|
- one
|
|
|
|
- two
|
|
|
|
|
2019-11-06 18:31:00 +01:00
|
|
|
# This comment should be kept.
|
|
|
|
# COMMENT_OUT
|
2018-09-30 00:03:11 +02:00
|
|
|
other: thing
|
|
|
|
'''
|
|
|
|
|
2019-09-18 23:11:56 +02:00
|
|
|
# flake8: noqa
|
2018-09-30 00:03:11 +02:00
|
|
|
expected_config = '''
|
2019-09-18 02:00:58 +02:00
|
|
|
# foo:
|
|
|
|
# bar:
|
|
|
|
# - baz
|
|
|
|
# - quux
|
2019-11-06 18:31:00 +01:00
|
|
|
|
2018-09-30 00:03:11 +02:00
|
|
|
location:
|
|
|
|
repositories:
|
|
|
|
- one
|
|
|
|
- two
|
2019-11-06 18:31:00 +01:00
|
|
|
|
|
|
|
# This comment should be kept.
|
2019-09-18 02:00:58 +02:00
|
|
|
# other: thing
|
2018-09-30 00:03:11 +02:00
|
|
|
'''
|
|
|
|
|
|
|
|
assert module._comment_out_optional_configuration(config.strip()) == expected_config.strip()
|
|
|
|
|
|
|
|
|
2020-11-19 00:01:10 +01:00
|
|
|
def testrender_configuration_converts_configuration_to_yaml_string():
|
|
|
|
yaml_string = module.render_configuration({'foo': 'bar'})
|
2018-09-30 00:03:11 +02:00
|
|
|
|
2019-10-22 00:17:47 +02:00
|
|
|
assert yaml_string == 'foo: bar\n'
|
2018-09-30 00:03:11 +02:00
|
|
|
|
|
|
|
|
2017-07-09 20:41:55 +02:00
|
|
|
def test_write_configuration_does_not_raise():
|
2017-07-10 19:37:11 +02:00
|
|
|
flexmock(os.path).should_receive('exists').and_return(False)
|
2017-07-11 00:20:50 +02:00
|
|
|
flexmock(os).should_receive('makedirs')
|
2017-07-09 20:41:55 +02:00
|
|
|
builtins = flexmock(sys.modules['builtins'])
|
|
|
|
builtins.should_receive('open').and_return(StringIO())
|
2017-07-11 00:20:50 +02:00
|
|
|
flexmock(os).should_receive('chmod')
|
2017-07-09 20:41:55 +02:00
|
|
|
|
2018-09-30 00:03:11 +02:00
|
|
|
module.write_configuration('config.yaml', 'config: yaml')
|
2017-07-09 20:41:55 +02:00
|
|
|
|
|
|
|
|
2017-07-10 19:37:11 +02:00
|
|
|
def test_write_configuration_with_already_existing_file_raises():
|
|
|
|
flexmock(os.path).should_receive('exists').and_return(True)
|
|
|
|
|
|
|
|
with pytest.raises(FileExistsError):
|
2018-09-30 00:03:11 +02:00
|
|
|
module.write_configuration('config.yaml', 'config: yaml')
|
2017-07-10 19:37:11 +02:00
|
|
|
|
|
|
|
|
2017-07-11 00:20:50 +02:00
|
|
|
def test_write_configuration_with_already_existing_directory_does_not_raise():
|
|
|
|
flexmock(os.path).should_receive('exists').and_return(False)
|
|
|
|
flexmock(os).should_receive('makedirs').and_raise(FileExistsError)
|
|
|
|
builtins = flexmock(sys.modules['builtins'])
|
|
|
|
builtins.should_receive('open').and_return(StringIO())
|
|
|
|
flexmock(os).should_receive('chmod')
|
|
|
|
|
2018-09-30 00:03:11 +02:00
|
|
|
module.write_configuration('config.yaml', 'config: yaml')
|
2017-07-11 00:20:50 +02:00
|
|
|
|
|
|
|
|
2019-10-22 00:17:47 +02:00
|
|
|
def test_add_comments_to_configuration_sequence_of_strings_does_not_raise():
|
|
|
|
config = module.yaml.comments.CommentedSeq(['foo', 'bar'])
|
|
|
|
schema = {'seq': [{'type': 'str'}]}
|
|
|
|
|
|
|
|
module.add_comments_to_configuration_sequence(config, schema)
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_comments_to_configuration_sequence_of_maps_does_not_raise():
|
|
|
|
config = module.yaml.comments.CommentedSeq([module.yaml.comments.CommentedMap([('foo', 'yo')])])
|
|
|
|
schema = {'seq': [{'map': {'foo': {'desc': 'yo'}}}]}
|
|
|
|
|
|
|
|
module.add_comments_to_configuration_sequence(config, schema)
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_comments_to_configuration_sequence_of_maps_without_description_does_not_raise():
|
|
|
|
config = module.yaml.comments.CommentedSeq([module.yaml.comments.CommentedMap([('foo', 'yo')])])
|
|
|
|
schema = {'seq': [{'map': {'foo': {}}}]}
|
|
|
|
|
|
|
|
module.add_comments_to_configuration_sequence(config, schema)
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_comments_to_configuration_map_does_not_raise():
|
2017-07-09 20:41:55 +02:00
|
|
|
# Ensure that it can deal with fields both in the schema and missing from the schema.
|
|
|
|
config = module.yaml.comments.CommentedMap([('foo', 33), ('bar', 44), ('baz', 55)])
|
2018-09-30 07:45:00 +02:00
|
|
|
schema = {'map': {'foo': {'desc': 'Foo'}, 'bar': {'desc': 'Bar'}}}
|
2017-07-09 20:41:55 +02:00
|
|
|
|
2019-10-22 00:17:47 +02:00
|
|
|
module.add_comments_to_configuration_map(config, schema)
|
2017-07-09 20:41:55 +02:00
|
|
|
|
|
|
|
|
2019-11-06 18:31:00 +01:00
|
|
|
def test_add_comments_to_configuration_map_with_skip_first_does_not_raise():
|
|
|
|
config = module.yaml.comments.CommentedMap([('foo', 33)])
|
|
|
|
schema = {'map': {'foo': {'desc': 'Foo'}}}
|
|
|
|
|
|
|
|
module.add_comments_to_configuration_map(config, schema, skip_first=True)
|
|
|
|
|
|
|
|
|
|
|
|
def test_remove_commented_out_sentinel_keeps_other_comments():
|
|
|
|
field_name = 'foo'
|
|
|
|
config = module.yaml.comments.CommentedMap([(field_name, 33)])
|
|
|
|
config.yaml_set_comment_before_after_key(key=field_name, before='Actual comment.\nCOMMENT_OUT')
|
|
|
|
|
|
|
|
module.remove_commented_out_sentinel(config, field_name)
|
|
|
|
|
|
|
|
comments = config.ca.items[field_name][module.RUAMEL_YAML_COMMENTS_INDEX]
|
|
|
|
assert len(comments) == 1
|
|
|
|
assert comments[0].value == '# Actual comment.\n'
|
|
|
|
|
|
|
|
|
|
|
|
def test_remove_commented_out_sentinel_without_sentinel_keeps_other_comments():
|
|
|
|
field_name = 'foo'
|
|
|
|
config = module.yaml.comments.CommentedMap([(field_name, 33)])
|
|
|
|
config.yaml_set_comment_before_after_key(key=field_name, before='Actual comment.')
|
|
|
|
|
|
|
|
module.remove_commented_out_sentinel(config, field_name)
|
|
|
|
|
|
|
|
comments = config.ca.items[field_name][module.RUAMEL_YAML_COMMENTS_INDEX]
|
|
|
|
assert len(comments) == 1
|
|
|
|
assert comments[0].value == '# Actual comment.\n'
|
|
|
|
|
|
|
|
|
|
|
|
def test_remove_commented_out_sentinel_on_unknown_field_does_not_raise():
|
|
|
|
field_name = 'foo'
|
|
|
|
config = module.yaml.comments.CommentedMap([(field_name, 33)])
|
|
|
|
config.yaml_set_comment_before_after_key(key=field_name, before='Actual comment.')
|
|
|
|
|
|
|
|
module.remove_commented_out_sentinel(config, 'unknown')
|
|
|
|
|
|
|
|
|
2017-07-09 20:41:55 +02:00
|
|
|
def test_generate_sample_configuration_does_not_raise():
|
|
|
|
builtins = flexmock(sys.modules['builtins'])
|
|
|
|
builtins.should_receive('open').with_args('schema.yaml').and_return('')
|
2019-11-06 18:31:00 +01:00
|
|
|
flexmock(module.yaml).should_receive('round_trip_load')
|
|
|
|
flexmock(module).should_receive('_schema_to_sample_configuration')
|
|
|
|
flexmock(module).should_receive('merge_source_configuration_into_destination')
|
2020-11-19 00:01:10 +01:00
|
|
|
flexmock(module).should_receive('render_configuration')
|
2019-11-06 18:31:00 +01:00
|
|
|
flexmock(module).should_receive('_comment_out_optional_configuration')
|
|
|
|
flexmock(module).should_receive('write_configuration')
|
|
|
|
|
|
|
|
module.generate_sample_configuration(None, 'dest.yaml', 'schema.yaml')
|
|
|
|
|
|
|
|
|
|
|
|
def test_generate_sample_configuration_with_source_filename_does_not_raise():
|
|
|
|
builtins = flexmock(sys.modules['builtins'])
|
|
|
|
builtins.should_receive('open').with_args('schema.yaml').and_return('')
|
|
|
|
flexmock(module.yaml).should_receive('round_trip_load')
|
|
|
|
flexmock(module.load).should_receive('load_configuration')
|
2017-07-09 20:41:55 +02:00
|
|
|
flexmock(module).should_receive('_schema_to_sample_configuration')
|
2019-11-06 18:31:00 +01:00
|
|
|
flexmock(module).should_receive('merge_source_configuration_into_destination')
|
2020-11-19 00:01:10 +01:00
|
|
|
flexmock(module).should_receive('render_configuration')
|
2018-09-30 00:03:11 +02:00
|
|
|
flexmock(module).should_receive('_comment_out_optional_configuration')
|
|
|
|
flexmock(module).should_receive('write_configuration')
|
2017-07-09 20:41:55 +02:00
|
|
|
|
2019-11-06 18:31:00 +01:00
|
|
|
module.generate_sample_configuration('source.yaml', 'dest.yaml', 'schema.yaml')
|